小池啓仁 ヒロヒト応援ブログ By はてな

小池啓仁(コイケヒロヒト)の動画など。

小池啓仁 ヒロヒト応援ブログ By はてな

Perlでファクトリメソッドパターン! (デザインパターン)

Perlデザインパターン 第4弾(ファクトリメソッドパターン)

ファクトリメソッドパターンとは、スーパークラスで処理の枠組みを定め、サブクラスでその具体的内容を定めるようなデザインパターンです。
なんだ、テンプレートメソッドパターンと同じじゃないか・・・と思ったあなた、さすがです。
だた違うのは、ファクトリメソッドパターンでは、抽象的なインスタンスを作成します。
そして、サブクラスで具象的なインスタンスを実装するのです。


以下のクラス図で示されているようにCreatorクラスのcreateメソッドで抽象メソッドfactoryMethodを利用して抽象的なインスタンスを作成します。
つぎに、具象クラスConreteCreatorでfactoryMethodをオーバーライドします。そのfactoryMethodには、Productクラスを継承したConreteProductオブジェクトが渡されるのです。


ファクトリメソッドパターンとは、抽象クラス(CreatorとProduct)で処理の枠組み(フレームワーク)定め、具象クラス(ConreteCreatorとConreteProduct)具体的な肉付けをするパターンです。


注目すべきは、抽象クラスには一切具象クラスが出て来ないことです。つまり、具象レベルがどのような実装になってもこのフレームワーク(抽象クラス)が使えるということです。

一般的なファクトリメソッドパターンのクラス図

     +---------------------+  Creates    +---------------------+                    
     |  Creator            |------------>| Product             |                    
     +---------------------+             +---------------------+                    
     |                     |             |                     |                    
     +---------------------+             +---------------------+                    
     |  create             |             |  method1            |                    
     |  factoryMethod      |             |  method2            |                    
     |                     |             |  method3            |                    
     |                     |             |                     |                    
     +---------------------+             +---------------------+                    
                #                                   #                               
                |                                   |                               
                |                                   |                               
                |                                   |                               
     +----------+----------+  Creates    +----------+----------+                    
     | ConreteCreator      |------------>| ConreteProduct      |                    
     +---------------------+             +---------------------+                    
     |                     |             |                     |                    
     +---------------------+             +---------------------+                    
     | factoryMethod       |             | method1             |                    
     |                     |             | method2             |                    
     |                     |             | method3             |                    
     +---------------------+             +---------------------+                    

サンプル

IDカードを作るサンプルです。
詳しくは、『Java言語で学ぶデザインパターン入門』に書かれています。

サンプルのクラス図
     +---------------------+  Creates    +---------------------+                    
     | Factory             |------------>| Product             |                    
     +---------------------+             +---------------------+                    
     |                     |             |                     |                    
     +---------------------+             +---------------------+                    
     |  create             |             |  use                |                    
     |  createProduct      |             |                     |                    
     |  registerProduct    |             |                     |                    
     |                     |             |                     |                    
     +---------------------+             +---------------------+                    
                #                                   #                               
                |                                   |                               
                |                                   |                               
                |                                   |                               
     +----------+----------+  Creates    +----------+----------+                    
     | IDCardFactory       |------------>| IDCard              |                    
     +---------------------+             +---------------------+                    
     | owners              |             | owner               |
     +---------------------+             +---------------------+                    
     | createProduct       |             | use                 |                    
     | registerProduct     |             | getOwner            |                    
     +---------------------+             +---------------------+                    

Product.pm

package Product;
use strict;

sub use { die "オーバーライド必須"; }
1;

Factory.pm

package Factory;
use strict;

sub create {
    my $self = shift;
    my $owner = shift;
    my $p = $self->createProduct($owner);
    $self->registerProduct($p);
    return $p;
}
sub createProduct { die "オーバーライド必須"; }
sub registerProduct { die "オーバーライド必須"; }
1;

IDCard.pm

package IDCard;
use strict;
use base 'Product';

sub new {
    my $class = shift;
    my $self = {};
    $self->{owner} = shift;
    print "$self->{owner}のカードを作ります。\n";
    return bless $self, $class;
}
sub use {
    my $self = shift;
    print "$self->{owner}のカードを使います。\n";
}
sub getOwner {
    my $self = shift;
    return $self->{owner};
}
1;

IDCardFactory.pm

package IDCardFactory;
use strict;
use IDCard;
use base 'Factory';

sub new {
    my $class = shift;
    my $self = {};
    $self->{owners} = [];
    return bless $self, $class;
}
sub createProduct {
    my $self = shift;
    my $owner = shift;
    return IDCard->new($owner);
}
sub registerProduct {
    my $self = shift;
    my $product = shift;
    push @{$self->{owners}}, $product->getOwner();
}
1;

Main.pl

use strict;
use IDCardFactory;

my $factory = IDCardFactory->new;
my $card1 = $factory->create('まちゃ');
my $card2 = $factory->create('やちゅ');
my $card3 = $factory->create('ヒロ');
$card1->use();
$card2->use();
$card3->use();

Main.plの実行結果

C:\Documents and Settings\dp\FactoryMethod>perl main.pl
まちゃのカードを作ります。
やちゅのカードを作ります。
ヒロのカードを作ります。
まちゃのカードを使います。
やちゅのカードを使います。
ヒロのカードを使います。


尚、本コンテンツは、結城先生の以下の本をかなり参考にしています。
Javaデザインパターンを勉強したい人には、お勧めのご著書です!

増補改訂版Java言語で学ぶデザインパターン入門

増補改訂版Java言語で学ぶデザインパターン入門