Php 工厂模式合适吗?

Php 工厂模式合适吗?,php,design-patterns,Php,Design Patterns,那么 我在创建对象方面有一个问题(好的,没有真正的问题,但我想尝试一些新的东西)。实际上,我有一些订单,其中包含订单项列表 这些orderitems在整个应用程序中使用和分布,我需要一种创建它们的方法。主要问题是,我希望能够以多种不同的方式创建这些对象 实际上,我在类构造函数中这样做,并检查给定的参数是否正确。 (我使用的是php,因此您肯定知道该语言不支持重载:) 一个简单而快速的例子 class foo { protected $_data=null; public func

那么

我在创建对象方面有一个问题(好的,没有真正的问题,但我想尝试一些新的东西)。实际上,我有一些订单,其中包含订单项列表

这些orderitems在整个应用程序中使用和分布,我需要一种创建它们的方法。主要问题是,我希望能够以多种不同的方式创建这些对象

实际上,我在类构造函数中这样做,并检查给定的参数是否正确。 (我使用的是php,因此您肯定知道该语言不支持重载:)

一个简单而快速的例子

class foo {
    protected $_data=null;
    public function __contruct($bar){
        if (is_array($bar)){
            $this->_data=$bar;
        }
        else {
            $dataFromDb=getDataFromDatabase
            $this->_data=$dataFromDb;
        }
    }
}
无论如何,如果我想通过提供另一种类型的参数来创建我的对象,让我们假设一个封装在字符串中的xml文档,我需要将所有这些内容放入我的构造函数中。 如果创建对象的过程更复杂,我最终需要为每种类型创建一个单独的方法,我想初始化。但只有在创建此特殊类型时才调用此方法。(我想你有问题:))

我想到的另一个问题是,如果我需要在构造函数中使用更多的参数来创建一个具体的对象,那么我已经修改了我的所有代码,导致构造函数发生了更改。(好的,我可以给他越来越多的参数并使用默认值,但这不是我真正想要的)


所以我的问题是,哪种模式适合这个问题来解决我对具体对象的创建。我考虑为我想要创建具体对象的每种方式创建一个工厂。但我不确定这是否是解决此类问题的常见解决方案。

如果只是构造函数的签名发生了更改,我会这样做(Zend Framework通用构造函数):

这本质上意味着所有的构造函数参数都是带有命名键的数组元素,在初始化过程中,你想在这个数组中使用的任何东西都可以创建一个setter,然后自动调用它。不利的一面是IDE中缺乏有效的暗示

另一方面,如果您想要特定的构造函数,那么我可能会选择工厂,但仍然使用大致相同的方法:

class foo {

  public static function create($class, $options)
  {
     if(class_exists($class))
     {
        $obj = new $class($options);
     }
  }
}

当然,您也可以使用PHP的反射来确定如何调用构造函数,而不只是注入任意数组参数。

您可以简单地将其设置为带有可选参数的工厂:)


哇,示例一中的代码非常好。我花了一些时间来理解它,但如果它与我遇到的任何问题相匹配,我肯定会使用它。但在具体场景中,我认为你的第二个例子就是我想要的方式。因此,我创建了一个抽象的基类,并按照我想要创建对象的每一种方式在不同的类中执行特定的操作。谢谢你,你的例子真的启发了我。很高兴它有帮助。。。请不要我改变了一点构造器。。。我刚才很忙:-)谢谢你的快速回答。这也是一个很好的解决方案,但我认为我不能熟练地解决我的具体问题,因为我没有强制性和选择性的东西。我给my concrete构造函数的值不能分为这两类。它不限于强制/可选,它只是一个exmaple,您也可以只有1个参数或5个参数。模式是根据输入数据对新实例调用方法:)
class foo {

  public static function create($class, $options)
  {
     if(class_exists($class))
     {
        $obj = new $class($options);
     }
  }
}
class Example_Factory
{
    public static function factory($mandatoryParam, $optionalParam = null)
    {
        $instance = new self;
        $instance->setMandatory($mandatoryParam);

        if ($optionalParam !== null) {

            $instance->setOptional($optionalParam);
        }

        return $instance;
    }

    public function setMandatory($in)
    {
        // do something....
    }

    public function setOptional($in)
    {
        // do some more...
    }
}