gpt4 book ai didi

php - 具有对象初始化的工厂类 - 尽量避免静态

转载 作者:可可西里 更新时间:2023-11-01 12:51:53 24 4
gpt4 key购买 nike

我正在尝试为我们的系统设计一组工厂类,工厂创建的一些对象也需要初始化才能正常使用。

例子:

$foobar = new Foobar();
$foobar->init( $qux, ... );
// $foobar ready for usage

对于相同的示例,假设 $qux object 是唯一的依赖 Foobar需要。我想说的是:

$foobar = Foo_Factory( 'bar' );

为了避免传递 $qux 的需要跨整个系统的对象并将其作为另一个参数传递给工厂类,我想执行 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;
}

}

想到的解决方案很少,但没有一个是理想的:

  1. $qux 添加一个静态setter 方法到工厂类,并让它存储对 $qux 的引用在私有(private)静态变量中。系统可以设置$qux在开始时,工厂类可以防止任何 future 的更改(出于安全原因)。
    虽然这种方法有效,但使用静态参数来存储对 $qux 的引用。在单元测试期间存在问题(例如,由于其静态,它在各个测试之间愉快地生存)。
  2. 使用单例模式创建一个新的上下文类,让工厂类使用它来获取对 $qux 的引用.这可能比选项 #1 更简洁(尽管我们将静态问题从工厂类移到了上下文类)。
  3. 一直使用依赖注入(inject),即传递$qux任何使用工厂类的对象,并让该对象将其作为另一个参数传递给工厂类:Foo_Factory::getFoo($type, $qux); .
  4. 同上(#3),但不是传递 $qux沿着系统,改为传递工厂类的实例(即在这种情况下,它不是静态的,而是可实例化的)。

请问有什么推荐的?上面提到的四种替代方案中的任何一种,或者有更好的方法吗?

注意:我不想进入 static is evil在这里进行 flamewar,只是想找到最好的解决方案。

最佳答案

我会一直使用依赖注入(inject)。但是,与其到处传递 $qux,不如将其注册到依赖注入(inject)器容器中,然后让容器对其进行分类。在 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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com