Subclassing the Singleton class
这个问题我想了二天, 不得其解, 希望高手解决:
在GOF的《Design patterns》中, 说到子类化一个单件问题。
我们先不讨论应不应该子类化一个单件问题(除非你提供十分有力的证据)。
论点一:
在书中:作者说到Singleton有一些优点:
“Permits refinement of operations and representation[color=#FF0000][/color].The Singleton class may be subclassed, and it's easy to configure an application with an instance of this extended class. You can configure the application with an instance of the class you need at run-time. ”
论点二:
作者在讲述Abstract Factory实现时, 说到:“Factories as singletons[color=#FF0000][/color]. An application typically needs only one instance of a ConcreteFactory per product family.”
那么作者做错了一件事, 而且是两次。
这件事是这样的。
在子类化一个Singleton时,
论点三:
“The registry maps between string names and singletons. When Instance needs a singleton, it consults the registry, asking for the singleton by name.”
子类化一个单件可能有两种情况:
1, 只有一个子类单件在整个程序运行期间被用到。程序运行起来决定。
2, 所有的子类单件都可以在整个程序运行期间被用到。论点二和论点三证明作者想干这件事,
看作者给出的作者单件注册表源码:
class Singleton { public: static void Register(const char* name, Singleton*); static Singleton* Instance(); protected: static Singleton* Lookup(const char* name); private: static Singleton* _instance; static List<NameSingletonPair>* _registry; };Singleton* Singleton::Instance () { if (_instance == 0) { const char* singletonName = getenv("SINGLETON"); // user or environment supplies this at startup _instance = Lookup(singletonName); // Lookup returns 0 if there's no such singleton } return _instance; }MazeFactory* MazeFactory::Instance () { if (_instance == 0) { const char* mazeStyle = getenv("MAZESTYLE"); if (strcmp(mazeStyle, "bombed") == 0) { _instance = new BombedMazeFactory; } else if (strcmp(mazeStyle, "enchanted") == 0) { _instance = new EnchantedMazeFactory; // ... other possible subclasses } else { // default _instance = new MazeFactory; } } return _instance; }
我(Application)出版了一本字典,仅仅我自己用(Singleton),你告诉我你的名字,我可以查你是否对同性恋者保持友好的态度。
写完费了一个小时...晕...
[解决办法]
从语义语境上来理解:
如果将某个类做成Singleton,就表明在实际使用中这类东西只会存在一个,即使这个类可能有很多子类,在所有这些子类中也只能有一个被实例化。如果每一个子类都要被实例化,那就不应该将他们的父类做成Singleton,而应该将每一个子类中分别做成Singleton。
从语法上理解:
Singleton模式的原始手段有二:一是将构造函数隐藏,不允许外部执行实例化。二在类内部用静态变量,实际应用中不光可以是单子,也可以做成二子、三子,或者N个对象的池子,你想咋样就咋样。如果和其它模式合作(如工厂),那是另外的事情,与单子没有本质的关联。
[解决办法]
那个,换本好点的讲设计模式的书吧。
gof的书太老了,基本已经被评价为误导大于正导了。
关于singleton,看<Pattern Hatching>和<modern c++ design>
其它模式,看《敏捷软件开发:原则、模式与实践》
[解决办法]
设计模式就不错啊;楼主能发现问题,具有怀疑精神,那就进行下去;
[解决办法]