Chain of Responsibility パターン
次は、Chain of Responsibility パターン。
意味は以下のとおり理解しました。
それぞれ異なる処理機能をもった実装クラスが複数存在するとし、
それらを管理する親クラスが存在します。
親クラスに対してある処理依頼をした時、
親クラスは実装クラスに対して順番に依頼を行い、
処理を担当できる実装クラスが存在すれば処理を実施します。
{ package DeliveryImpl; use Moose::Role; requires 'delivery'; no Moose::Role; 1; } { package Delivery; use Moose; use MooseX::AttributeHelpers; has 'deliveries' => ( metaclass => 'Collection::Array', is => 'ro', isa => 'ArrayRef[DeliveryImpl]', default => sub { [] }, provides => { 'push' => 'add_request', } ); __PACKAGE__->meta->make_immutable; no Moose; sub delivery { my ( $self, $type, $comment ) = @_; my $handled; my $list = $self->deliveries; foreach my $handler (@$list) { $handled = $handler->delivery( $type, $comment ); } } 1; } { package Delivery::Susi; use Moose; with 'DeliveryImpl'; __PACKAGE__->meta->make_immutable; no Moose; sub delivery { my ( $self, $type ) = @_; if ( $type eq 'Susi' ) { print $type , "を作る\nヘイ!お待ち!\n"; } } 1; } { package Delivery::Udon; use Moose; with 'DeliveryImpl'; __PACKAGE__->meta->make_immutable; no Moose; sub delivery { my ( $self, $type ) = @_; if ( $type eq 'Udon' ) { print $type , "を作る\nヘイ!お待ち!\n"; } } 1; } { package main; my $wk = Delivery->new; $wk->add_request( Delivery::Susi->new() ); $wk->add_request( Delivery::Udon->new() ); $wk->delivery( 'Susi' ); $wk->delivery( 'Udon' ); 1; }
拙い例ですが、上記のコードはある出前屋さんをイメージしました。
出前には、すしを配達するDelivery::Susiクラスと、
うどんを配達するDelivery::Udonクラスがありました。
そして上記2クラスを管理するDeliveryクラスがありました。
Delivery::SusiクラスとDelivery::Udonクラスには、
deliveryメソッドが存在し、deliveryを定義づけしているのは、
DeliveryImplクラスです。
メソッドを新たに追加する場合は、まずDeliveryImplクラスで定義を行います。
勘違いとかありましたら、ご指摘いただければありがたく思います。
よろしくお願いいたします.
Mooseもデザインパターンもそうですが、とても高度で、他にまず理解すべきことは山ほどあるのですが、せっかく学びはじめたので、しっかり理解できればと思います。