According to the article, it is suggested to not use a singleton. However, what is the alternative or better way? For example, in my GUI, I have a log window. After an operation, no matter where it is, I can easily record some information in the log window if a singleton is used. The singleton provides a shortcut, although via a global route. If not using singleton, any good way to do it? Note the operations may scatter anywhere. Thanks a lot!
2 回答
做可能可行的最简单的事情。根据我的经验,进行日志记录的最简单方法是使用免费函数。
void logError(const std::string& message);
void logWarning(const std::string& message);
void logInfo(const std::string& message);
也许实施只是一个全球性的,也许不是。你如何实现它并不重要。重要的是他们不会根据实现方式编写不同的代码。专注于暴露的界面。
恕我直言,单身人士很糟糕,因为它们以后很难改变。不是因为它们的实现方式,而是因为它们倾向于只允许背后有一个单例的接口。这很难改变。当改变很困难时,维护成本会很高。
关于 Singleton 有几个常见的误解。
首先是它具有任何兑换功能并且很有用。错误的。真是废话。
第二个误解是它的意思是“只有一个对象”。没有。它的意思是“执行只能有一个对象的规则”。那不是一回事。
Gang of Four Design Patterns一书中的 Singleton 模式是一种“创建模式”,因为它的作用与对象的创建方式有关。所谓模式的目的是提供一个对象的单个全局实例,并防止创建其他实例。例如,将构造函数设为私有并提供一个静态函数,该函数只允许创建一个实例。(它在一种类型中具有两种责任的事实应该是它被破坏的线索,它违反了单一责任原则。)
如果您必须有一个全局实例,那么(尽管这可能是设计不佳的一个征兆)您只需创建一个. 那么你就不需要“执行规则只能有一个”属性,所以你不需要单例“模式”。
太多人说“它是 Singleton”的意思是“只有一个”,这与说“我已经使用语言规则保证只能有一个”是不一样的。
或者他们说“我有一个单身人士”,好像这证明有一个全局变量是合理的。给它起一个花哨的名字并不能成为垃圾设计的借口。
如果您需要一个实例,请创建一个实例。不要创建更多。宾果游戏,你有一个实例。简单的。如果您无法控制程序的其他位如何访问该实例,那么您的程序已经损坏。修复代码。停止依赖该类型的单个实例。阻止创建其他实例并不能解决您的设计问题,只会使情况变得更糟。
这是Just Create One模式。
如果大量代码需要访问该对象,则将其传递给代码(通过构造函数或函数参数),因此依赖关系是显式的。这是Parameterize from Above模式。
对于日志记录模块,想要记录的代码不应该关心它正在记录到“单例”(即不能有多个实例的类型,)它应该记录到它传递的记录器,或者它应该通过一个不需要是“单例”的全局函数或对象,它可以只是一个只有一个的全局函数或对象。您是编写代码来强制执行只有一个规则std::cout
并调用std::cout::instance()
,还是只是接受它是一个全局规则并使用它?你打电话printf::instance()("%s", ...)
还是只是printf
让实施者printf
担心它是如何工作的?