我正在尝试为我们的系统设计一组工厂类,其中一些由工厂创建的对象也需要初始化,然后才能正确使用它们。
例子:
$foobar = new Foobar();
$foobar->init( $qux, ... );
// $foobar ready for usage
对于同一示例,可以说
$qux
对象是Foobar
所需的唯一依赖项。我想要得到的是:$foobar = Foo_Factory( 'bar' );
为了避免在整个系统中传递
$qux
对象并将其作为另一个参数传递给factory类,我想直接在factory类中执行Foobar
的初始化:class Foo_Factory {
public static function getFoo( $type ) {
// some processing here
$foo_name = 'Foo' . $type;
$foo = new $foo_name();
$foo->init( $qux );
return $foo;
}
}
想到的解决方案很少,但都不是理想的解决方案:
$qux
的静态setter方法添加到工厂类,并将其对$qux
的引用存储在私有(private)静态变量中。系统可以在开始时设置$qux
,并且工厂类可以防止将来发生任何更改(出于安全原因)。尽管这种方法行得通,但在单元测试期间使用静态参数存储对$qux
的引用还是有问题的(例如,幸福地生活在两次测试之间)由于其静态,因此需要进行个别测试)。 $qux
的引用。这可能比选项#1干净一些(尽管我们将静态问题从工厂类移到了上下文类)。 $qux
传递给使用factory类的任何对象,然后将该对象作为另一个参数传递给factory类:Foo_Factory::getFoo($type, $qux);
。 $qux
,而是传递factory类的实例(即,在这种情况下,它不是静态的,而是可实例化的)。 您会推荐什么?上面提到的四种选择中的任何一种,还是有更好的方法来做到这一点?
注意:我不想在这里陷入
static is evil
的大战,只是想提出最好的解决方案。 最佳答案
我将一路使用Dependency Injection。但是,与其在各处传递$ qux,不如在Dependency Injector容器中注册它,然后让该容器对其进行整理。用Symfony Component说:
// Create DI container
$container = new sfServiceContainerBuilder();
// Register Qux
$container->setService('qux', $qux);
// Or, to have the DI instanciate it
// $container->register('qux', 'QuxClass');
// Register Foobar
$container->register('foobar', 'Foobar')
->addArgument(new sfServiceReference('qux'));
// Alternative method, using the current init($qux) method
// Look! No factory required!
$container->register('altFoobar', 'Foobar')
->addMethodCall('init', array(new sfServiceReference('qux')));
关于php - 带对象初始化的工厂类-尝试避免静态,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5486921/