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