那么,
我有一个问题(好吧,没有真正的问题,但我想尝试新的东西)和创建对象。实际上我有一些订单,其中包含一个订购项目列表。
这些订单项在整个应用程序中使用并传播,我需要一种方法来创建它们。主要问题是,我希望能够以多种不同的方式创建这些对象。
实际上我在类构造函数中执行此操作并检查是否给出了参数。 (我正在使用php,所以你肯定不会知道该语言的重载支持:))
一个简单快捷的例子
class foo {
protected $_data=null;
public function __contruct($bar){
if (is_array($bar)){
$this->_data=$bar;
}
else {
$dataFromDb=getDataFromDatabase
$this->_data=$dataFromDb;
}
}
}
无论如何,如果我想通过提供另一种类型的参数来创建我的对象,让我们说一个封装在字符串中的xml文档我需要将所有这些东西放在我的构造函数中。 如果创建对象的过程更复杂,我最终需要为每种类型创建一个单独的方法,我想启动。但只有在创建此特殊类型时才会调用此方法。 (我认为你遇到了问题:))
另一个问题浮现在脑海中,如果我在构造函数中需要更多参数来创建具体对象,我已经修改了所有代码,导致构造函数发生了变化。 (好吧,我可以给他越来越多的参数并使用默认值,但这不是我真正想要的。)
所以我的问题是,哪种模式适合这个问题来解决我创建的具体对象。我想为我想要创建具体对象的每种方式创建一个工厂。但我不确定这是否是解决此类问题的常用解决方案。
答案 0 :(得分:2)
如果只改变构造函数的签名,我会这样做(Zend Framework的通用构造函数):
class foo {
// params
public function __construct($options = null)
{
if(null !== $options)
{
$this->setOptions($options);
}
}
public function setOptions(array $options){
foreach ($options as $name => $value){
$method = 'set' . $name;
if(method_exists($this, $method)
{
$this->$method($value);
}
}
return $this;
}
}
这个ess理论上所有的构造函数参数都是带有命名键的数组元素,以及在初始化过程中你想要在这个数组中使用的任何东西,你为它创建一个setter然后自动调用它。缺点是IDE中缺乏有效的暗示。
另一方面,如果你想拥有特定的构造函数,那么我可能会选择工厂,但仍然使用相同的方法:
class foo {
public static function create($class, $options)
{
if(class_exists($class))
{
$obj = new $class($options);
}
}
}
当然,您也可以使用PHP的反射来确定如何调用构造函数而不是仅注入任意数组参数。
答案 1 :(得分:1)
你可以简单地把它变成一个带有可选参数的工厂:)
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...
}
}