设计模式——单例模式(Singleton)

保证一个类仅有一个实例,并提供一个访问它的全局访问点。——DP

UML类图

设计模式——单例模式(Singleton)

模式说明

个人认为单例模式是所有设计模式中最为简单的一个模式,因为实现这个模式仅需一个类,而不像其他模式需要若干个类。这个模式中,需要注意的一点就是获取实例时的线程安全问题。

通常单例模式的实现方式如下:

   class ToolBox

    {

        // 阻止外部实例化ToolBox

        private ToolBox()

        {

            guid = Guid.NewGuid();

        }



        private static ToolBox instance;

        private static object lockObj = new object();



        //提供一个全局访问点

        public static ToolBox GetToolBoxInstance()

        {

            if (instance != null) return instance;



            //要考虑线程安全问题

            lock (lockObj)

            {

                if (instance == null)

                {

                    instance = new ToolBox();

                }

            }



            return instance;

        }



        #region 用于测试



        private Guid guid;



        public void ShowGuid()

        {

            Console.WriteLine(guid.ToString());

        }



        #endregion



    }

另外,C#语言中提供一种“静态初始化”功能,对静态初始化器的调用是由CLR控制的,并且CLR会解决线程安全问题,保证只调用一次。所以也可以利用这个特性,来简化单例模式的C#实现:

    class ToolBox2

    {

        // 阻止外部实例化ToolBox2

        private ToolBox2() { guid = Guid.NewGuid(); }



        //静态内联初始化

        private static readonly ToolBox2 instance = new ToolBox2();



        //提供一个全局访问点

        public static ToolBox2 GetToolBoxInstance()

        {

            return instance;

        }



        #region 用于测试



        private Guid guid;



        public void ShowGuid()

        {

            Console.WriteLine(guid.ToString());

        }



        #endregion

    }

客户端访问代码如下(从输出可以看到,每次访问获取的都是同一个实例):

        static void Main(string[] args)

        {

            // 测试单例模式

            for (int i = 0; i < 10; i++)

            {

                new Thread(x =>

                    ToolBox.GetToolBoxInstance().ShowGuid()

                    ).Start();

            }



            Thread.Sleep(200);

            Console.WriteLine();



            // 测试单例模式

            for (int i = 0; i < 10; i++)

            {

                new Thread(x =>

                    ToolBox2.GetToolBoxInstance().ShowGuid()

                    ).Start();

            }



            /* 输出如下

            f38db210-20bc-4c2d-8d43-40a0e58fedd5

            f38db210-20bc-4c2d-8d43-40a0e58fedd5

            f38db210-20bc-4c2d-8d43-40a0e58fedd5

            f38db210-20bc-4c2d-8d43-40a0e58fedd5

            f38db210-20bc-4c2d-8d43-40a0e58fedd5

            f38db210-20bc-4c2d-8d43-40a0e58fedd5

            f38db210-20bc-4c2d-8d43-40a0e58fedd5

            f38db210-20bc-4c2d-8d43-40a0e58fedd5

            f38db210-20bc-4c2d-8d43-40a0e58fedd5

            f38db210-20bc-4c2d-8d43-40a0e58fedd5



            8398be29-abd3-4abd-abf8-4fd09641427c

            8398be29-abd3-4abd-abf8-4fd09641427c

            8398be29-abd3-4abd-abf8-4fd09641427c

            8398be29-abd3-4abd-abf8-4fd09641427c

            8398be29-abd3-4abd-abf8-4fd09641427c

            8398be29-abd3-4abd-abf8-4fd09641427c

            8398be29-abd3-4abd-abf8-4fd09641427c

            8398be29-abd3-4abd-abf8-4fd09641427c

            8398be29-abd3-4abd-abf8-4fd09641427c

            8398be29-abd3-4abd-abf8-4fd09641427c

            */



            Console.ReadKey();

        }

总结

单例模式和前面介绍的工厂模式(工厂方法、抽象工厂)都属于创建型模式,负责类的实例化过程。单例模式的实现过程,只需要一个类,算是最简单的一个模式,在多线程环境下,单例模式的实现必须保证线程安全,否则在多个线程同时访问时,可能产生多个实例。在C#中,可以通过语言本身的特性(静态初始化器)来更简洁地实现单例模式。

参考

  1. 程杰老师  《大话设计模式》

你可能感兴趣的:(Singleton)