首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C++ >

Subclassing the Singleton class解决办法

2012-03-05 
Subclassing the Singleton class这个问题我想了二天, 不得其解, 希望高手解决:在GOF的《Design patterns》

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, 所有的子类单件都可以在整个程序运行期间被用到。论点二和论点三证明作者想干这件事, 

看作者给出的作者单件注册表源码:

C/C++ code
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;    }


客户端第一次请求子类化单件时, 先设定环境变量, 再请求,不会有问题,
如果所有的子类单件都可以在整个程序运行期间被用到,这时,
客户端再次请求子类单件, 因为请求过一次, 所以_instance不会为0, 而是请求到上一次的单件。

来看作者的第二处同样的失误:
C/C++ code
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;    }

一样, 它只适用于只有一个子类单件在整个程序运行期间被用到。如果
所有的子类单件都可以在整个程序运行期间被用到。那么上面的实现还是有问题。

结论:
作者有逻辑上的失误, 一方面我们从论点中可以看出作者子类化一个单件, 应该是所有的子类单件都可以在程序中被用到。
除非作者故意隐藏某些东西。

Google和baidu应为我已经做过了, 除了国外网站没有看。

请高人点精。

谢谢大家看完问题。

[解决办法]
你是想讨论“Subclassing the Singleton class”好不好,对不对?

首先,如果讨论这种做法是否正确(对不对?)是完全没有必要的,就像UI设计,简单没错,花里胡哨也没错,就算部分是简洁的,部分是花里胡哨的,那也不能说错。

要讨论“好不好?”,那也很难,继续说我的UI设计,有的时候可能是需要简单的,有的时候可能是需要花里胡哨的,有些设计是大家一致认为美的,有些设计是非主流的。

OK,理解?理解万岁,下面乱侃...

代码一、very and 很ok,没问题吧?
代码二、迷宫工厂,回忆玩Heroes2时,选择一个地图,(我总是玩impossible),假如这个地图是自己制作的,这个地图class在你选择地图时是不知道的。
1. 你请求地图
2. 系统加载地图
好像上面没用到Abstract Factory,继续回忆:星际争霸,建立自己的地图时,你可以建立RPG地图,或者对战地图
1. 你请求对战地图加载器
2. 系统给你一个地图加载器
3. 你请求加载地图
4. 加载器加载地图
你明白“你”是谁了吗?用UML的话来说“你”就是Actor,My God,从设计模式跑到了UML,上面的步骤好像也跟use case的步骤很像

"An application typically needs only one instance of a ConcreteFactory per product family"
应用程序需要一个“对战地图加载器“,因为我现在想玩对战游戏

“The registry maps between string names and singletons. When Instance needs a singleton, it consults the registry, asking for the singleton by name.”


我(Application)出版了一本字典,仅仅我自己用(Singleton),你告诉我你的名字,我可以查你是否对同性恋者保持友好的态度。


写完费了一个小时...晕...

[解决办法]
从语义语境上来理解:
如果将某个类做成Singleton,就表明在实际使用中这类东西只会存在一个,即使这个类可能有很多子类,在所有这些子类中也只能有一个被实例化。如果每一个子类都要被实例化,那就不应该将他们的父类做成Singleton,而应该将每一个子类中分别做成Singleton。

从语法上理解:
Singleton模式的原始手段有二:一是将构造函数隐藏,不允许外部执行实例化。二在类内部用静态变量,实际应用中不光可以是单子,也可以做成二子、三子,或者N个对象的池子,你想咋样就咋样。如果和其它模式合作(如工厂),那是另外的事情,与单子没有本质的关联。
[解决办法]
那个,换本好点的讲设计模式的书吧。
gof的书太老了,基本已经被评价为误导大于正导了。
关于singleton,看<Pattern Hatching>和<modern c++ design>
其它模式,看《敏捷软件开发:原则、模式与实践》
[解决办法]
设计模式就不错啊;楼主能发现问题,具有怀疑精神,那就进行下去;
[解决办法]

探讨
那个,换本好点的讲设计模式的书吧。
gof的书太老了,基本已经被评价为误导大于正导了。
关于singleton,看 <Pattern Hatching>和 <modern c++ design>
其它模式,看《敏捷软件开发:原则、模式与实践》

热点排行