根据the article,建议不要使用单身人士。但是,替代或更好的方式是什么?例如,在我的GUI中,我有一个日志窗口。在操作之后,无论它在哪里,如果使用单例,我都可以在日志窗口中轻松记录一些信息。单身人士提供了捷径,尽管通过全球路线。如果不使用单身,有什么好办法吗?请注意,操作可能分散在任何地方。非常感谢!
答案 0 :(得分:3)
做最简单的事可能有用。根据我的经验,最简单的记录方法是使用自由函数。
void logError(const std::string& message);
void logWarning(const std::string& message);
void logInfo(const std::string& message);
也许实施只是一个全球性的,也许不是。你如何实现它并不重要。它的重要性在于它们不会根据它的实现方式编写不同的代码。专注于暴露的界面。
恕我直言,单身人士很糟糕,因为他们以后很难改变。不是因为它们的实现方式,而是因为它们倾向于只允许在其后面有单例的接口。这很难改变。当改变很困难时,维护成本很高。答案 1 :(得分:2)
关于辛格尔顿有几种常见的误解。
首先,它具有任何兑换功能,并且非常有用。错误。这是废话。
第二个误解是它意味着“只有一个对象”。 否即可。这意味着“强制执行只能一个对象的规则”。那不是一回事。
Gang of Four 设计模式书中的Singleton模式是一个“Creational Pattern”,因为它的作用与创建对象的方式有关。所谓模式的目的是提供对象的单个全局实例,并防止创建其他实例。例如使构造函数成为私有的,并提供一个静态函数,只允许创建一个实例。 (它在一种类型中有两个责任的事实应该是它被破坏的线索,它违反了single responsibility principle。)
如果你必须有一个全局实例,那么(尽管这可能是设计不佳的一个症状)你可以通过只创建一个来完成。那么你不需要“强制规则只有一个”属性,所以你不需要Singleton“模式”。
太多人说“这是一个单身人士”,当他们的意思是“只有一个”时,这与说“我使用语言规则来保证只能有”不一样其中之一“。
或者他们说“我有一个单身人士”,好像有理由拥有一个全局变量。给它一个奇特的名字并不能成为垃圾设计的借口。
如果您需要一个实例,请创建一个实例。不要创造更多。宾果,你有一个实例。简单。如果您无法控制程序的其他位如何访问该实例,那么您的程序已经被破坏。修复代码。停止依赖该类型的单个实例。防止创建其他实例并不能解决您的设计问题,只会让情况变得更糟。
这是Just Create One模式。
如果许多代码需要访问该对象,则将其传递给代码(通过构造函数或函数参数),因此依赖项是显式的。这是Parameterize from Above模式。
对于日志记录模块,想要记录的代码不应该关心它是否记录到“Singleton”(即一个不能有多个实例的类型),它应该记录到它传递的记录器,或者它应该通过一个全局函数或对象来记录,它不需要是一个“Singleton”它只能是一个只有一个的全局函数。您是否编写代码来强制执行规则只有一个std::cout
并调用std::cout::instance()
或者您是否接受它是全局的并使用它?你打电话给printf::instance()("%s", ...)
还是只打printf
并让printf
的实施者担心它是如何运作的?