Singleton 与 MonoState 模式

 

1. Singleton 模式的不同实现形式

 

 1) 最简单的Sigleton (无线程同步, 不适应多线程环境)

  

   using System;

 

    public class Singleton

    {

        private static Singleton instance;

       

        private Singleton() { }

       

        public static Singleton GetInstance() {            

            if (instance == null) {

                instance = new Singleton();

            }

           

            return instance;

        }

    }

 

 2) 著名的Double check 方式(有同步控制, 可以用于多线程环境)

 

    这种方式实现也不复杂,需要注意的是,在.Net 平台下,由于优化的需要,JIT 编译器有


    可能调整语句顺序,因此要
使用易失字段(C#使用volatile 关键字)避免这种情况的发生。

 

    using System;

 

    public class Singleton

    {

        private static volatile Singleton instance;

        private static readonly object lockHelper = new object();

       

        private Singleton() { }

       

        public static Singleton GetInstance() {             

            if (instance == null) {

                lock(lockHelper) {

                    if (instance == null) {

                        instance = new Singleton();

                    }

                }

            }

           

            return instance;

        }

    }

 

 3) 事实上,.net编译器可能为我们带来麻烦,同时我们也可以利用.net运行时的特点实现更为


    简洁的多线程
Singleton, 那就是 static 构造器,我们知道,static 构造函数是由.net 


    runtime
调用的,用户不可直接调用,并且它保证即使在多线程模式下,static 构造函数


    也只会被执行一次,也可以这么说,
.net 运行时免费为我们加了锁,那么我们就可以利用这个


    特点,来实现更为简洁的
Singleton (当然也适应多线程环境), 实现如下:

 

    using System;

 

    public class Singleton

    {

        private static Singleton instance;

       

        static Singleton() {

            instance = new Singleton();

        }

       

        private Singleton() { }

       

        public static Singleton GetInstance() {

            return instance;

        }

    }

 

    如果我们更加的崇尚简洁,则可以使用内联的方式来初始化instance, 实现如下:

 

    using System;

 

    public class Singleton

    {

        private static Singleton instance  = new Singleton();

       

        private Singleton() { }

       

        public static Singleton GetInstance() {

            return instance;

        }

    }

 

    当然,更为简洁的做法是:

 

    using System;

 

    public class Singleton

    {

        public static readonly Singleton Instance  = new Singleton();

       

        private Singleton() { }

    }

 

 

Singleton 模式的主要优点:

 

    1). 适用于任何类.

 

    2). 可以通过派生创建,无论基类是否为Singleton, 子类都可以实现为Singleton

 

    3). Lazy loading: 如果从来没有使用过一个Singleton , 它就不会占用内存。

 

Sigleton 模式的代价:

   

    1). 销毁方法没有定义:Singleton 一旦被加载,将一直存在于内存,直到应用程序卸载,无法销毁,

 

        即使将其设置为null, 系统的各个对象仍然可能拥有它的引用,再次调用时,将再次产生一个实

 

        例,如果在C++ 这个的系统中,这样的操作还有可能导致系统的崩溃。

       

    2). 效率问题:每次调用都要执行if 语句,而大部分情况下是多余的,不过这个问题只在第一种方式实现的

 

        Singleton 模式中存在。

        

    3). Singleton 的子类天然不是Singleton, 必须重新实现。

   

    4). 丧失多态性。

   

    5). 不透明性:客户程序必须知道它正在使用一个Singleton, 因为必须使用GetInstance() 才能创建

 

        实例。

 

 

 

2. MonoState 的实现及其与Singleton 的比较

 

         Monostate是另一种获得系统某个类别对象都表现为一个对象的实现方式,Singleton模式重在



     通过保证系统
中只有唯一实例,而Monostate模式重在保证唯一状态, 当然Singleton模式更多的是用来



     保证唯一实例。

 

    Monostate模式更多关注的是行为,即行为上的一致;Singleton模式更多关注的是结构,强制结构上的


    单一,仅
产生唯一实例,下面是MonoState 模式的实现:

 

    using System;

 

    public class Mono

    {

        private int a;

        private int b;

       

        public Mono(int a, int b) {

            this.a = a;

            this.b = b;

        }

       

        public int A {

            get {

                return this.a;

            }

            set {

                this.a = value;

            }

        }

       

        public int B {

            get {

                return this.b;

            }

            set {

                this.b = value;

            }

        }

    }

 

    public class MonoState

    {

        private static Mono mono;

       

        public MonoState() {

            mono = new Mono(10, 20);

        }

       

        public Mono Mono {

            get {

                return mono;

            }

            set {

                mono = value;

            }

        }

    }

 

    internal static class TestApp

    {

        private static void Main() {

            MonoState monoState1 = new MonoState();

            monoState1.Mono.A = 200;

           

            MonoState monoState2 = new MonoState();

            monoState2.Mono.B = 400;

           

            Console.WriteLine(object.ReferenceEquals(monoState1.Mono, monoState2.Mono));

        }

    }

 

Monostate模式比Singleton模式有着一些优势和特点:

 

    1). 没有到底谁负责销毁的问题,你可以在你不想Monostate对象的时候将它销毁,因为它和任何

   
         其他的对象没有任何区别。

 

    2). MonoState 的子类天然就是MonoState

 

    3). 可以表现多态性,因为Mono (或者实现为两个方法)不是static 的,因此可以override.

 

    4). 透明性:用户并不需要也不关心是否使用了Monostate模式对象,原因还是Monostate对象和其


         他对象是一样的。

 

当然Monostate模式也有自己的限制和代价:

 

    1). 内存占用:即使不使用Monostate对象,也要占用内存,因为有static成员变量。

 

    2). 效率:因为Monostate模式中创建的是真正的对象,因此需要创建和销毁开销。

   

    3). 不可转换:无法把一个非MonoState 的对象通过子类化变为MonoState.

 

参考: Agile Software Development

        Principles, Patterns, and Practices

 

posted on 2007-12-24 20:00  优哉@游哉  阅读(1142)  评论(3编辑  收藏  举报

导航