use strict;
use warnings;
{
package Display;
use strict;
use warnings;
sub new {
my ($class, $impl, ) = @_;
my $self = {
impl => $impl,
};
return bless $self, $class;
}
sub open { $_[0]->{impl}->rawOpen(); }
sub print { $_[0]->{impl}->rawPrint(); }
sub close { $_[0]->{impl}->rawClose(); }
sub display {
$_[0]->open();
$_[0]->print();
$_[0]->close();
}
}
{
package StringDisplayImpl;
use strict;
use warnings;
use Encode;
our @ISA = qw/DisplayImpl/;
sub new {
my ($class, $string, ) = @_;
my $self = {
string => $string,
width => length(decode('UTF-8', $string)),
};
return bless $self, $class;
}
sub rawOpen { $_[0]->printLine(); }
sub rawPrint { print "|".$_[0]->{string}."|\n"; }
sub rawClose { $_[0]->printLine(); }
sub printLine {
print "+";
print "-" for(1..$_[0]->{width});
print "+\n";
}
}
{
package CountDisplay;
use strict;
use warnings;
our @ISA = qw/Display/;
sub new {
my ($class, $impl) = @_;
return $class->SUPER::new($impl);
}
sub multiDisplay {
my ($self, $count) = @_;
$self->open();
$self->print() for(1..$count);
$self->close();
}
}
{
package DisplayImpl;
use strict;
use warnings;
sub rawOpen { die; }
sub rawPrint { die; }
sub rawClose { die; }
}
my $d01 = Display->new(StringDisplayImpl->new('Hello Japan!'));
my $d02 = CountDisplay->new(StringDisplayImpl->new('YOROSIKU'));
$d01->display();
$d02->display();
$d02->multiDisplay(10);