【发布时间】: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