在PHP(<;5.3)中创建动态工厂方法

在PHP(<;5.3)中创建动态工厂方法,php,dynamic,factory,Php,Dynamic,Factory,通常如何在PHP中创建动态工厂方法?所谓动态工厂方法,我指的是一种工厂方法,它将根据给定参数的某些方面自动发现要创建的对象。最好也不要先在工厂登记。不过,我同意将可能的对象放在一个公共位置(目录) 我希望避免在factory方法中使用典型的switch语句,例如: public static function factory( $someObject ) { $className = get_class( $someObject ); switch( $className )

通常如何在PHP中创建动态工厂方法?所谓动态工厂方法,我指的是一种工厂方法,它将根据给定参数的某些方面自动发现要创建的对象。最好也不要先在工厂登记。不过,我同意将可能的对象放在一个公共位置(目录)

我希望避免在factory方法中使用典型的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();
    }
}

我希望能够在不涉及工厂实现的情况下,为这些项目插入新的可投票项目和投票存储库。

如果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);       
    }
}

你能进一步解释为什么投票库需要知道它给出了什么样的
Votable
实现吗?@strager:是的,投票库最初将基于每个Votable项的一个db表。这是为了在我觉得需要将某个特定项目的投票权转移到其他地方时,使它们保持轻量级,并可用于其他类型的存储库。@strager:不过你给了我一些思考的东西。我突然意识到,如果我想用另一份回购协议替换某一特定项目的一份回购协议,我可能还需要联系工厂但是,由于这是一个特定的情况,我仍然想知道一种在其他情况下实现这一点的好方法。投票库本身中不能有
Votable
子类数据库表名的映射吗?存储库有一个数据表名,可以用某个子类来标识它,factory方法使用映射创建一个子类。@strager:这也是可能的。我想我得再仔细考虑一下。谢谢你的建议。我很感激。