Singleton与MonoState模式

作者: 沪上最强亚巴顿 | 来源:发表于2015-10-23 17:44 被阅读853次

当需要强制要求某个特定对象只能有单一实例时,可以使用Singleton或者MonoState模式完成.
首先看下两种模式的经典实现代码(代码摘自网络http://www.codethinked.com/the-monostate-pattern).

public class Singleton
{
    private static Singleton instance;
 
    private Singleton()
    {
    }
 
    public static Singleton Instance
    {
        get
        {
            if (instance == null)
            {
                instance = new Singleton();
            }
            return instance;
        }
    }
 
    public String DataItem { get; set; }
}
public class Monostate
{
    private static string dataItem;
    public string DataItem
    {
        get { return dataItem; }
        set { dataItem = value; }
    }
 
    public Monostate(){ }
}

对于Singleton模式,关注的是Structural Constraint,即只有一个实例. 该模式具有以下的优势:

  1. 跨平台.使用合适的中间件,能够把该模式扩展为跨多个JVM.
  2. 适合于任何类,针对任意普通类,通过简单的改造都可以成为Singleton的.
  3. 延迟创建.只有在第一次调用Instance来获取该单一实例时,才会进行实例的创建工作.

而对于该模式也有不少的抱怨, 最大的问题在于类创建方式的不透明性. 假设现在有一个Service类需要实现为Singleton的, 那么该Service的所有使用者都需要被通知到,要使用Instance方法(getter),而非new的方式来获取该类的实例.
另一个较为严重的问题是可能的内存泄露.如果在Singleton类中持有一些全局资源,那么是没有合适的时机进行资源释放的.

MonoState模式部分解决了Singleton模式的缺陷,它关注的是Behaviour. 该模式具有以下的优势:

  1. 透明性.对于创建者而已,创建MonoState类的实例和创建普通类的实例是一致的(通过new()).这减少了沟通成本.
  2. 可派生性. MonoState的派生类也具有MonoState性的. 这主要是因为子类和父类共享相同的static数据域. MonoState的继承, 可以看做是基于相同数据下的行为多态性的派生.

当派生类也需要具有单实例特性时,MonoState模式的优势是巨大的,MonoState子类天生就是MonoState的.
当然,MonoState模式也是有争议的,最大的争议当属static数据域的恰当性. 全局static数据,是导致不少程序Bug的源头. 其次由于静态数据是单个JVM作用域内的,所以它是不可跨JVM的.

当我们需要单实例特性时,如果知会使用者要使用Instance而非new来获取实例不会造成麻烦,那么Singleton模式会是首选. 而当需要保证MonoState是可继承时,使用MonoState模式是不错的选择.

相关文章

网友评论

    本文标题:Singleton与MonoState模式

    本文链接:https://www.haomeiwen.com/subject/ywbthttx.html