【问题标题】:Create dynamic factory method in PHP (< 5.3)在 PHP 中创建动态工厂方法 (< 5.3)
【发布时间】: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:这也是一种可能。我想我得再考虑一下。感谢您的建议。我很感激。

标签: php dynamic factory


【解决方案1】:

如果 switch 语句不存在,那么您基本上只能遵循命名约定。获取传入对象的类并使用它来实例化新类。下面是一个简单的例子。

//pseudo code, untested
class Default_VoteRepositoryFactory
{
    public static function factory( Voteable $item, $arg1, $arg2 )
    {
        $parts = explode('_', get_class($item));
        $type  = array_pop();
        $class = 'Default_VoteRepository_' . $type;
        return new $class($arg1, $arg2);
        // autodiscover what type of repository this item needs
        // for instance, Default_User needs a Default_VoteRepository_User
        // etc...
    }
    //can be as complex or as simple as you need
    protected static function getType(stdClass $item)
    {
        $parts = explode('_', get_class($item));
        return array_pop($parts);       
    }
}

【讨论】:

    猜你喜欢
    • 2010-10-17
    • 2011-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多