1.Singleton

definition

Ensure a class has only one instance and provide a global point of access to it.

确保一个类只有一个实例,并提供一个全局的访问点。

Frequency of use:   medium high

UML class diagram

participants

    The classes and/or objects participating in this pattern are:

  • Singleton   (LoadBalancer)
    • defines an Instance operation that lets clients access its unique instance. Instance is a class operation.
    • responsible for creating and maintaining its own unique instance.

sample code in C#

This structural code demonstrates the Singleton pattern which assures only a single instance (the singleton) of the class can be created.

Show code

// Singleton pattern -- Structural example

using System;

namespace DoFactory.GangOfFour.Singleton.Structural
{
  
   // MainApp test application

   class MainApp
  {
    
     static void Main()
    {
       // Constructor is protected -- cannot use new
      Singleton s1 = Singleton.Instance();
      Singleton s2 = Singleton.Instance();

       if (s1 == s2)
      {
        Console.WriteLine("Objects are the same instance");
      }

       // Wait for user
      Console.Read();
    }
  }

   // "Singleton"

   class Singleton
  {
     private static Singleton instance;

     // Note: Constructor is 'protected'
     protected Singleton()
    {
    }

     public static Singleton Instance()
    {
       // Use 'Lazy initialization'
       if (instance == null)
      {
        instance = new Singleton();
      }

       return instance;
    }
  }
}

Output
Objects are the same instance




This real-world code demonstrates the Singleton pattern as a LoadBalancing object. Only a single instance (the singleton) of the class can be created because servers may dynamically come on- or off-line and every request must go throught the one object that has knowledge about the state of the (web) farm.

Show code

// Singleton pattern -- Real World example

using System;
using System.Collections;
using System.Threading;

namespace DoFactory.GangOfFour.Singleton.RealWorld
{
  
   // MainApp test application

   class MainApp
  {
     static void Main()
    {
      LoadBalancer b1 = LoadBalancer.GetLoadBalancer();
      LoadBalancer b2 = LoadBalancer.GetLoadBalancer();
      LoadBalancer b3 = LoadBalancer.GetLoadBalancer();
      LoadBalancer b4 = LoadBalancer.GetLoadBalancer();

       // Same instance?
       if (b1 == b2 && b2 == b3 && b3 == b4)
      {
        Console.WriteLine("Same instance\n");
      }

       // All are the same instance -- use b1 arbitrarily
       // Load balance 15 server requests
       for ( int i = 0; i < 15; i++)
      {
        Console.WriteLine(b1.Server);
      }

       // Wait for user
      Console.Read();    
    }
  }

   // "Singleton"

   class LoadBalancer
  {
     private static LoadBalancer instance;
     private ArrayList servers = new ArrayList();

     private Random random = new Random();

     // Lock synchronization object
     private static object syncLock = new object();

     // Constructor (protected)
     protected LoadBalancer()
    {
       // List of available servers
      servers.Add("ServerI");
      servers.Add("ServerII");
      servers.Add("ServerIII");
      servers.Add("ServerIV");
      servers.Add("ServerV");
    }

     public static LoadBalancer GetLoadBalancer()
    {
       // Support multithreaded applications through
       // 'Double checked locking' pattern which (once
       // the instance exists) avoids locking each
       // time the method is invoked
       if (instance == null)
      {
         lock (syncLock)
        {
           if (instance == null)
          {
            instance = new LoadBalancer();
          }
        }
      }

       return instance;
    }

     // Simple, but effective random load balancer

     public string Server
    {
       get
      {
         int r = random.Next(servers.Count);
         return servers[r].ToString();
      }
    }
  }
}

Output
Same instance

ServerIII
ServerII
ServerI
ServerII
ServerI
ServerIII
ServerI
ServerIII
ServerIV
ServerII
ServerII
ServerIII
ServerIV
ServerII
ServerIV




This .NET optimized code demonstrates the same code as above but uses more modern, built-in .NET features.

Here an elegant .NET specific solution is offered. The Singleton pattern simply uses a private constructor and a static readonly instance variable that is lazily initialized. Thread safety is guaranteed by the compiler.

Show code

// Singleton pattern -- .NET optimized

using System;
using System.Collections;

namespace DoFactory.GangOfFour.Singleton.NETOptimized
{
  
   // MainApp test application

   class MainApp
  {
    
     static void Main()
    {
      LoadBalancer b1 = LoadBalancer.GetLoadBalancer();
      LoadBalancer b2 = LoadBalancer.GetLoadBalancer();
      LoadBalancer b3 = LoadBalancer.GetLoadBalancer();
      LoadBalancer b4 = LoadBalancer.GetLoadBalancer();

       // Confirm these are the same instance
       if (b1 == b2 && b2 == b3 && b3 == b4)
      {
        Console.WriteLine("Same instance\n");
      }

       // All are the same instance -- use b1 arbitrarily
       // Load balance 15 requests for a server
       for ( int i = 0; i < 15; i++)
      {
        Console.WriteLine(b1.Server);
      }

       // Wait for user
      Console.Read();    
    }
  }
  
   // Singleton

   sealed class LoadBalancer
  {
     // Static members are lazily initialized.
     // .NET guarantees thread safety for static initialization
     private static readonly LoadBalancer instance =
       new LoadBalancer();

     private ArrayList servers = new ArrayList();
     private Random random = new Random();

     // Note: constructor is private.
     private LoadBalancer()
    {
       // List of available servers
      servers.Add("ServerI");
      servers.Add("ServerII");
      servers.Add("ServerIII");
      servers.Add("ServerIV");
      servers.Add("ServerV");
    }

     public static LoadBalancer GetLoadBalancer()
    {
       return instance;
    }
    
     // Simple, but effective load balancer
     public string Server
    {
       get
      {
         int r = random.Next(servers.Count);
         return servers[r].ToString();
      }
    }
  }
}

Output
Same instance

ServerIV
ServerIV
ServerIII
ServerV
ServerII
ServerV
ServerII
ServerII
ServerI
ServerIV
ServerIV
ServerII
ServerI
ServerV
ServerIV

转载于:https://www.cnblogs.com/huang/archive/2007/03/22/684014.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值