2005年07月07日
selectトリガを使ったClass::DBIのFactoryパターン
以前からClass::DBIでFactoryパターンを使えたらなーと思ってました。
たとえば、有料、無料、VIPのように複数の会員タイプがあるような会員サイトを作る場合、Class::DBIを継承したMyService::MemberがFactoryとなり、会員のタイプによって、MyService::Member::Basic, MyService::Member::Free, MyService::Member::VIPというようなサブクラスのインスタンスを作成するというようなイメージです。
さらにFactoryクラスでMyService::Member->retrieve_allとかすると、適切なサブクラスのインスタンスのリストがとれると最高です。
そんなことができないかなーとClass::DBIのドキュメントやソースを眺めていたんですが、Class::DBIに組み込まれているselectトリガを使えば実現できそうだったので、試してみました。
selectトリガはインスタンス生成時に必ず呼ばれているので、ここで会員のタイプを判別し、サブクラスにreblessしてやります。ソースコードはこんな感じです。このコードそのままではないですが、実際に同じようなコードを書いて試してみたところ、うまく動いているようです。
*MyService::Member - Factory
package MyService::Member
use base qw(Class::DBI);
require MyService::Member::Basic
require MyService::Member::Free
require MyService::Member::VIP
__PACKAGE__->set_db('Main', @datasource);
__PACKAGE__->table('member');
__PACKAGE__->columns(Primary => qw(member_id));
__PACKAGE__->columns(Essential => qw(member_type name age));
# select トリガにrebless用のメソッドをセット
__PACKAGE__->add_trigger( select => \&_rebless );
# サブクラスにrebless
sub _rebless {
my $self = shift;
#会員タイプ(member_type)でreblesするサブクラスを選択
my $class = 'MyService::Member::Basic';
if ($self->member_type eq 'Free'){
$class = 'MyService::Member::Free';
} elsif($self->member_type eq 'VIP'){
$class = 'MyService::Member::VIP';
}
bless $self, $class;
}
# abstract method
sub is_free {}
sub monthly_cost {}
* MyService::Member::Basic - 一般会員
package MyService::Member::Basic;
use strict;
use base qw(MyService::Member);
sub is_free { 0 } # 無料ではない
sub monthly_cost { 500 } # 月額500円
* MyService::Member::Free - 無料会員
package MyService::Member::Free;
use strict;
use base qw(MyService::Member);
sub is_free { 1 } # 無料
sub monthly_cost { 0 } # 月額0円
* MyService::Member::VIP - VIP会員
package MyService::Member::VIP;
use strict;
use base qw(MyService::Member);
sub is_free { 0 } # 無料ではない
sub monthly_cost { 250 } # VIPは月額250円
Continuing the discussion...
このエントリーのトラックバックURL:
http://hori-uchi.com/mt/trackback/358
このリストは、次のエントリーを参照しています: selectトリガを使ったClass::DBIのFactoryパターン:
selectトリガを使ったClass::DBIのFactoryパターン - ho...
続きを読む: Class::DBIのFactoryパターンをプラグイン化
from Lost-Season at 2005年07月07日 23:05
