Factoryパターン

各クラスの意味や必要性がわかりにくい、といった場合は実装に近い側から読んでいくと掴める場合がよくある。今回は「工場で作ったカードを使う」ということが簡単に読み取れる。
コーディングもIDcardFactoryのnewから書き始めて、必要な部分を書いて、最後に抽象化できるところをAbstractとしてまとめた。
AbstractクラスはどんなProductやFactoryが来ても変更されることはなさそう。つまりフレームになっているということか。

use strict;
use warnings;

{
    package Abstract::Product;
    use strict;
    use warnings;
    sub use { die "HOGEHOGE"; }
}

{
    package Abstract::Factory;
    use strict;
    use warnings;
    sub create {
        my ($self, $owner) = @_;
        my $product = $self->createProduct($owner);
        return $product;
    }
}

{
    package IDcard;
    use strict;
    use warnings;
    our @ISA = qw/Abstract::Product/;
    sub new {
        my ($class, $owner) = @_;
        my $self = {
            owner => $owner,
        };
        return bless $self, $class;
    }
    sub use {
        my ($self, ) = @_;
        print $self->{owner}, " no card wo tukaimasu!\n";
    }
}

{
    package IDcardFactory;
    use strict;
    use warnings;
    our @ISA = qw/Abstract::Factory/;
    sub new {
        my ($class, ) = @_;
        my $self = {};
        return bless $self, $class;
    }
    sub createProduct {
        my ($self, $owner) = @_;
        return IDcard->new($owner);
    }
}

my $factory = IDcardFactory->new();
my $card01 = $factory->create('Taro');
my $card02 = $factory->create('Jiro');
$card01->use();
$card02->use();