【问题标题】:Could Factory pattern be a generic Singleton?工厂模式可以是通用的单例吗?
【发布时间】:2012-03-08 15:08:32
【问题描述】:

factory 不是一般的单例吗?或者有时工厂模式可能是单例模式? 假设我们有以下工厂模式类:

abstract class Factory {

    /* This cache contains objects that has already been called.
    ** It stores the class name, arguments and the object itself.
    ** If an another call for the same class with the same arguments 
    ** is made we return the object.
    */ 
    private static $cache;

    public static function __callStatic($class, $args) {
        // 1) we check if the class already exists in the cache

            // 2) if it does then we return the object in the cache

            // 3.1) otherwise we create a new object
            // 3.2) we pass to the constructor of that object the arguments with ReflectionClass
            // 3.3) we store the class name, arguments and object in the cache
    }

}

还有一个具体的类

class My extends Factory {}

假设我们有一个类DontKnow($arg1, $arg2),它接受构造函数的参数$arg1 和$arg2。假设我们有另一个类DoNot(),它不接受构造函数的任何参数。

现在当我们打电话时

My::DontKnow('sample', 3);

我们返回一个对象,该对象现在存储在我们工厂类的缓存中。 如果我们再次调用它,我们的工厂类将不会实例化一个新对象,但会再次使用它。

例如,如果我们设置My::DontKnow('sample', 3)->setSomething('key', 'myvalue'); 并在另一个范围内调用My::DontKnow('sample', 3)->getSomething('key');,它将打印myvalue。

但是如果我们调用My::DoNot(),工厂类将返回DoNot() 类的“单例”对象,因为我们的工厂类My 是静态的,具有静态作用域并且可以在任何地方调用。

这不是单例的另一个例子吗?这和单例模式一样要避免吗?

【问题讨论】:

  • 工厂不一定,甚至通常不会缓存它创建的对象,工厂通常也不是静态调用的。您描述的是注册表或单例,而不是工厂。
  • @deceze,但这是一个工厂类。它只是静态地产生对象。这是真的,没有必要这样做。但它可能会发生。这不是单例。除了它是静态的之外,它与单例无关。
  • 仅仅因为你称它Factory并不意味着它是一个。 :) 你拥有的是一个静态的 Singleton Registry Factory Service Locator,而不仅仅是一个简单的工厂。
  • 你怎么称呼它并不重要。但是你想要达到什么目标更为重要。它做它应该做的吗?它封装了吗?是松耦合等吗?@deceze 很好的答案! +1

标签: php singleton overloading factory


【解决方案1】:

不,不是。您所描述的将是工厂模式的特殊用例,或者根本不是工厂。一个简单的工厂不做“实例管理”,它只是返回所需具体子类的一个新实例。

工厂方法本身是静态的,并不意味着返回的子类的方法是静态的。顾名思义,工厂生产具有非静态功能的具体对象。

http://sourcemaking.com/design_patterns/factory_method

【讨论】:

  • 好的,应该避免还是可以使用?
  • 您的这个静态 Singleton Registry Factory 服务定位器?我不知道,这取决于...如果可以避免的话,我认为您不应该这样做。它是否使单元测试更加困难?是的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-23
  • 1970-01-01
  • 2019-08-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-06
相关资源
最近更新 更多