我正在经历单身人士的负面影响。这是我完全无法理解的一点。这是链接和要点。
Singleton的负面
针对Singleton模式使用以下几点:
他们偏离单一责任原则。单例类有责任创建自己的实例 与其他业务职责。但是,这个问题可以 通过将创建部件委托给工厂对象来解决。
Singleton类不能被分类。
http://www.codeproject.com/Articles/307233/Singleton-Pattern-Positive-and-Negative-Aspects
答案 0 :(得分:2)
这篇文章似乎主要是关于单例的正常Java实现,其中构造函数是私有的;这意味着子类化是不可能的(子类需要调用构造函数,但不能)。允许更多访问单例意味着不再能保证只有一个实例。
这确实是一个固有的矛盾;如果你可以继承,那么你可以平凡地创建更多的实例(只需为你想要的每个实例创建一个空的子类),这样你就没有单独的实例。
答案 1 :(得分:1)
原始GoF书籍在Singleton的 Implementation 部分中说明了以下内容。注意:Instance
与Java getInstance()
相同。
- 确保唯一的实例 [...]
- 对Singleton类进行子类化。主要问题不是定义子类,而是安装其唯一的实例,以便客户端能够使用它。本质上,引用单例实例的变量必须使用子类的实例进行初始化。最简单的方法是确定要在Singleton的
醇>Instance
操作中使用哪个单例。示例代码中的一个示例显示了如何使用环境变量实现此技术。
选择Singleton子类的另一种方法是将Instance
的实现从父类中取出并放入它在子类中。这让C ++程序员在链接时决定单例类(例如,通过在包含不同实现的目标文件中链接),但是将它从单例的客户端隐藏起来。
链接方法修复了链接时单例类的选择,这使得在运行时很难选择单例类。使用条件语句来确定子类更加灵活,但它可以硬连接可能的Singleton类集。在所有情况下,这两种方法都不够灵活。
更灵活的方法使用单身人士登记。 Singleton类可以在众所周知的注册表中按名称注册其单例实例,而不是让Instance
定义可能的Singleton类集。
注册表映射字符串名称和单例。当Instance
需要单身时,它会咨询注册表,按名称要求单身人士。
GoF书籍继续展示注册管理机构的运作方式。
这里是使用环境变量的示例代码:
现在让我们考虑当有子类时会发生什么......我们将通过环境变量选择[subtype] [...]
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;
}