Singleton绝对是最滥用和滥用的模式之一。我们中的许多人已经在某一时刻感染过单一炎症。奇怪的是,它的近亲Monostate不那么有名,而且使用较少。您对Monostate有何看法?善还是恶?它是使用Singleton的更好选择吗?您是否也会像使用Singleton一样阻止其使用?
答案 0 :(得分:7)
嗯,monostate 是 Singleton ...所以它有完全相同的问题。
答案 1 :(得分:5)
仅仅因为使用模式怎么样?
更新:滥用单身人士是因为人们添加了没有理由的模式。它经常增加任意约束,没有任何好处。使用monostate w / o理由可能不那么有害,但没有理由。如果宇宙不会崩溃,如果有多个实例,则不要使用模式强制执行 - 只需创建一个实例。
答案 2 :(得分:5)
根据Monostates的定义,请注意:
“Monostates与SingletonsAreEvil同样是邪恶的。”
我不一定同意。基本前提是Singletons和Monostates是全局变量,因为Globals是邪恶的,所以也必须是Singletons和Monostates。
这种推理的问题在于它没有考虑为什么全局变量是邪恶的。 Globals主要是因为它们是可以在本地范围意外之外访问的变量,类似于非类型语言通常只允许通过引用变量来创建变量。
Singletons和Monostates不会导致同样的问题,因为它几乎不可能“意外地”引用全局静态,调用它的实例方法,然后使用该实例。
换句话说,全局变量是邪恶的,因为它们会导致细微而难以察觉的问题。单身人士和单身人士不会引起同样的问题,所以我不会因为同样的原因而认为他们是邪恶的,这也是大多数人在这个论点中出错的地方。
现在,单身人士和单身人士会引起其他类型的问题吗?当然。显然,TDD人讨厌他们,因为他们很难通过自动化测试正确测试。好的,很好,但对于那些不使用TDD的人来说,这些问题并不存在。
当然,单身人士可能会被滥用。仅仅为了避免传递实例而使用它们的人滥用它们。我认为Monostates比单身人士更好。
许多人提出工厂模式而不是单身人士,但我觉得工厂只是花哨的单身生成器。不,没有静态“实例”方法,但它基本上做同样的事情(当工厂创建单个实例对象时)。 Factory.Create与Singleton.Instance没什么不同。
编辑:
与Globals相比,Singletons和Monostates的一个方面是它们是共享的,因此不是线程安全的。如果您计划执行多线程应用程序,这是一个问题,如果您知道这一点,您可以采取步骤序列化对共享对象的访问。因此,这可能是唯一一个通常会将所有三种类型都视为导致麻烦的区域。
答案 3 :(得分:4)
为什么你认为人们不鼓励使用单身人士?对单身人士进行彻底的概括就像对于结果,全局变量等进行全面的概括。他们所有人都有一席之地。这些东西都不是“邪恶的”,它们的误用并不会使它们使用不好,只是意味着它们需要正确使用。
答案 4 :(得分:4)
我对Monostate的最大问题是它可能会导致使用它的人感到困惑。一般来说,如果您创建一个对象的新实例,您希望它只是一个具有自己的状态和生命周期的新实例。我一般认为意想不到的行为是一件坏事,所以我更喜欢单身,因为你知道你在使用它时会得到什么。
至于这两种模式是否是邪恶的,单身人士往往会被滥用,但所有其他模式,转换语句,循环或其他任何你想提及的事情都是如此。
答案 5 :(得分:2)
以下是Gamma,Helm,Johnson和Vlissides的“设计模式:可重复使用的面向对象软件的元素”第127页的摘录。
时使用单例模式
它真的让单身人士变得邪恶只是因为他们被滥用和误解了吗?
答案 6 :(得分:1)
与Monostate的交易是你需要更少地了解对象的实现才能使用它。换句话说,你保存了几个键击,因为你不必调用对象getInstance方法(Singleton s = Singleton :: getInstance; s.Method();)来获取对象的引用,你只需使用普通的语言结构(Monostate ms; ms.Method();)。确实很好。
每个编程语言结构都可以被标记为邪恶,因为每个编程语言都可以被滥用。
合理使用时,我认为没有人是“邪恶的”或“好的”。
答案 7 :(得分:1)
具有单个实例但没有全局访问权限的类如何:
public class SingleInstance
{
private static boolean exhausted = false;
public SingleInstance()
{
if (exhausted)
{
throw new IllegalStateException("only one instance allowed");
}
exhausted = true;
[...]
}
[...]
}
这避免了Singleton和MonoState的问题,同时它强制并清楚地传达只有一个实例。