单例(Singleton)模式

一、 单例(Singleton)模式

  单例模式的特点:

    •   单例类只能有一个实例。
    •   单例类必须自己创建自己的唯一实例。
    •   单例类必须给所有其它对象提供这一实例。

  单例模式应用:

    •   每台计算机可以有若干个打印机,但只能有一个Printer Spooler,避免两个打印作业同时输出到打印机。
    •   一个具有自动编号主键的表可以有多个用户同时使用,但数据库中只能有一个地方分配下一个主键编号。否则会出现主键重复。

二、 Singleton模式的结构:

  Singleton模式包含的角色只有一个,就是Singleton。Singleton拥有一个私有构造函数,确保用户无法通过new直接实例它。

  除此之外,该模式中包含一个静态私有成员变量instance与静态公有方法Instance()。Instance方法负责检验并实例化自己,然后存储在静态成员变量中,

  以确保只有一个实例被创建。(关于线程问题以及C#所特有的Singleton将在后面详细论述)。

 三、  在什么情形下使用单例模式:

  使用Singleton模式有一个必要条件:在一个系统要求一个类只有一个实例时才应当使用单例模式。

  反过来,如果一个类可以有几个实例共存,就不要使用单例模式。

注意:

  不要使用单例模式存取全局变量。这违背了单例模式的用意,最好放到对应类的静态成员中。

  不要将数据库连接做成单例,因为一个系统可能会与数据库有多个连接,并且在有连接池的情况下,应当尽可能及时释放连接。

  Singleton模式由于使用静态成员存储类实例,所以可能会造成资源无法及时释放,带来问题。

     

   

    /// <summary>
    /// 单例(Singleton)模式
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        { 
            LoadBalancer b1 = LoadBalancer.GetLoadBalancer();
            LoadBalancer b2 = LoadBalancer.GetLoadBalancer();
            LoadBalancer b3 = LoadBalancer.GetLoadBalancer();
            LoadBalancer b4 = LoadBalancer.GetLoadBalancer();

            // 同一个实例?
            if ((b1 == b2) && (b2 == b3) && (b3 == b4))
                Console.WriteLine("Same instance");

            //做负载均衡
            Console.WriteLine(b1.Server);
            Console.WriteLine(b2.Server);
            Console.WriteLine(b3.Server);
            Console.WriteLine(b4.Server);

            Console.ReadLine();
        }
    }

    /// <summary>
    /// 单例模式——现实世界的例子
    /// Singleton 单例(LoadBalancer)
    /// </summary>
    public class LoadBalancer
    {
        private static LoadBalancer balancer;
        private ArrayList servers = new ArrayList();
        private Random random = new Random();

        //受保护的 构造函数
        protected LoadBalancer()
        {
            // 可用的服务器列表
            servers.Add("ServerI");
            servers.Add("ServerII");
            servers.Add("ServerIII");
            servers.Add("ServerIV");
            servers.Add("ServerV");
        }
        //方法 定义静态方法确保同时只有一个实例在操作
        public static LoadBalancer GetLoadBalancer()
        {
            //支持多线程应用程序通过
            // “双重检查锁定”模式,避免了
            // 锁定每次方法调用
            //balancer = null;
            if (balancer == null)
            {
                // 只有一个线程可以获得互斥锁
                Mutex mutex = new Mutex();
                mutex.WaitOne();

                if (balancer == null)
                    balancer = new LoadBalancer();

                mutex.Close();
            }
            return balancer;
        }

        public string Server
        {
            get
            {
                // 简单,但有效的随机负载均衡器
                int r = random.Next(servers.Count);
                return servers[r].ToString();
            }
        }
    }

 

 

 

 

 

 

 

 

 

posted @ 2014-04-24 16:48  dragon.net  阅读(186)  评论(0编辑  收藏  举报