Monostate是邪恶的单身人士的堂兄吗?

时间:2009-03-09 00:56:13

标签: design-patterns oop

Singleton绝对是最滥用和滥用的模式之一。我们中的许多人已经在某一时刻感染过单一炎症。奇怪的是,它的近亲Monostate不那么有名,而且使用较少。您对Monostate有何看法?善还是恶?它是使用Singleton的更好选择吗?您是否也会像使用Singleton一样阻止其使用?

8 个答案:

答案 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的问题,同时它强制并清楚地传达只有一个实例。