【发布时间】:2010-04-03 19:04:12
【问题描述】:
通常如何在 PHP 中创建动态工厂方法?通过动态工厂方法,我的意思是一种工厂方法,它将根据给定参数的某些方面自动发现要创建的对象。最好不要先在工厂注册。不过,我可以将可能的对象放在一个共同的地方(一个目录)。
我想避免你在工厂方法中典型的 switch 语句,例如:
public static function factory( $someObject )
{
$className = get_class( $someObject );
switch( $className )
{
case 'Foo':
return new FooRelatedObject();
break;
case 'Bar':
return new BarRelatedObject();
break;
// etc...
}
}
我的具体案例涉及工厂根据要投票的项目创建投票存储库。这些项目都实现了Voteable 接口。像这样的:
Default_User implements Voteable ...
Default_Comment implements Voteable ...
Default_Event implements Voteable ...
Default_VoteRepositoryFactory
{
public static function factory( Voteable $item )
{
// autodiscover what type of repository this item needs
// for instance, Default_User needs a Default_VoteRepository_User
// etc...
return new Default_VoteRepository_OfSomeType();
}
}
我希望能够为这些项目添加新的可投票项目和投票存储库,而无需触及工厂的实现。
【问题讨论】:
-
您能否进一步解释一下为什么投票存储库需要知道
Votable的实现是什么? -
@strager:是的,存储库最初将基于每个 Voteable item 的一个 db 表。如果我觉得需要将特定项目的投票定向到其他地方,这是为了保持它们的轻量级和可互换的某些其他类型的存储库。
-
@strager:不过你给了我一些思考。我突然意识到,如果我想用另一个 repo 替换特定项目的一个 repo,我可能仍然需要联系工厂。 :) 但是,由于这是一个特定情况,我仍然想知道在其他情况下实现此目的的好方法。
-
你不能在投票存储库本身中有
Votable子类数据库表名的映射吗?存储库有一个数据表名来标识它与某个子类,工厂方法使用映射创建一个子类。 -
@strager:这也是一种可能。我想我得再考虑一下。感谢您的建议。我很感激。