设计模式(一)Singlton

  • 单例定义:

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

  • 适用场景:

    1.) 当系统中某个类必须仅有一个实例对象,同时访问该系统的所有访问者必须访问同一个实例对象时,且该对象实例自身占用资源又不大时。

    2.) 在C/s应用程序中,当我们要保证某一个非模式窗口,只能显示一个实例时。

  • 举例适用场景:

    线程池(threadpool)、缓存(cache)、对话框、处理编好设置和注册表(registry)的对象、日志对象,充当打印机、显卡等设备的驱动程序对象。这些类对象只能有一个实例,如果造出多个实例,就会导致许多问题产生,例如:程序的行为异常、资源适用过量,或者是不一致的结果。

  • 实现推荐方案:   
 1 /// <summary>
 2     /// Description of SiteSettings.
 3     /// </summary>
 4     public class SiteSettings
 5     {
 6         private static SiteSettings instance=null;
 7         private static object locker=new object();
 8                 
 9         private SiteSettings()
10         {
11         }        
12         
13         public static SiteSettings Instance {
14             get {    
15                 if(instance==null)
16                 {
17                     Console.WriteLine("Install equals null.");
18                     lock(locker)
19                     {
20                         if(instance ==null)
21                         {
22                             Console.WriteLine("new SiteSettings instance.");
23                             instance=new SiteSettings();
24                         }
25                     }
26                 }
27                 return instance; 
28             }
29         }
30         
31         private bool siteClosed=false;
32         
33         public bool SiteClosed {
34             get { return siteClosed; }
35             set { siteClosed = value; }
36         }
37     }

  调用: 

 1 class Program
 2     {
 3         public static void Main(string[] args)
 4         {
 5             Console.WriteLine("Hello World!");
 6             
 7             // TODO: Implement Functionality Here
 8             
 9             Console.WriteLine(SiteSettings.Instance.SiteClosed);
10             Console.WriteLine(SiteSettings.Instance.SiteClosed);
11             SiteSettings.Instance.SiteClosed=true;
12             Console.WriteLine(SiteSettings.Instance.SiteClosed);
13                 
14             Console.Write("Press any key to continue . . . ");
15             Console.ReadKey(true);
16         }
17     }

   运行结果:

 

  • 其他实现方案:

  1.) 方案1     

/// <summary>
    /// Description of MemberBO.
    /// </summary>
    public class SiteSettings
    {
        private static SiteSettings instance=null;
        private static object locker=new object();
                
        private SiteSettings()
        {
        }        
        
        public static SiteSettings Instance {
            get {
                if(instance ==null){
                    Console.WriteLine("Install equals null.");
                    lock(locker){
                        Console.WriteLine("Enter locker.");                        
                        Console.WriteLine("new SiteSettings instance.");
                        instance=new SiteSettings();
                    }
                }
                return instance; 
            }
        }
        
        private bool siteClosed=false;
        
        public bool SiteClosed {
            get { return siteClosed; }
            set { siteClosed = value; }
        }
    }
View Code

    2.) 方案2:     

/// <summary>
    /// Description of MemberBO.
    /// </summary>
    public class SiteSettings
    {
        private static SiteSettings instance=null;
        private static object locker=new object();
                
        private SiteSettings()
        {
        }        
        
        public static SiteSettings Instance {
            get {                
                Console.WriteLine("Install equals null.");
                lock(locker){
                    if(instance ==null){
                        Console.WriteLine("Enter locker.");                        
                        Console.WriteLine("new SiteSettings instance.");
                        instance=new SiteSettings();
                    }
                }
  return instance; 
            }
        }
        
        private bool siteClosed=false;
        
        public bool SiteClosed {
            get { return siteClosed; }
            set { siteClosed = value; }
        }
    }
View Code

  3.) 方案3: 

/// <summary>
    /// Description of MemberBO.
    /// </summary>
    public class SiteSettings
    {
        private static SiteSettings instance=null;
        private static object locker=new object();
                
        private SiteSettings()
        {
        }        
        
        public static SiteSettings Instance {
            get {                
                    Console.WriteLine("Install equals null.");
                    if(instance ==null){                                            
                        Console.WriteLine("new SiteSettings instance.");
                        instance=new SiteSettings();
                    }
                }
                return instance; 
            }
        }
        
        private bool siteClosed=false;
        
        public bool SiteClosed {
            get { return siteClosed; }
            set { siteClosed = value; }
        }
    }
View Code

  4.) 方案4:

/// <summary>
    /// Description of SiteSettings.
    /// </summary>
    public class SiteSettings
    {
        private static SiteSettings instance= new SiteSettings();
                    
        private SiteSettings()
        {
        }        
        
        public static SiteSettings Instance {
            get {    
                return instance; 
            }
        }
        
        private bool siteClosed=false;
        
        public bool SiteClosed {
            get { return siteClosed; }
            set { siteClosed = value; }
        }
    }
View Code

  5.) 方案5:

/// <summary>
    /// Description of SiteSettings.
    /// </summary>
    public class SiteSettings
    {
        private static SiteSettings instance=null;
        private static object locker=new object();
        
        private SiteSettings()
        {
        }        
        
        public static SiteSettings GetInstance() {
            if(instance==null){
                locker(locker){
                    if(instance==null){
                        instance=new SiteSettings();
                    }
                }
            }
            return instance;             
        }
        
        private bool siteClosed=false;
        
        public bool SiteClosed {
            get { return siteClosed; }
            set { siteClosed = value; }
        }
    }
View Code
  • 为什么不推荐方案1,方案2,方案3:
  1. 方案1,虽然考虑了线程安全,但还不是足够的安全,还没有双重锁定安全
  2. 方案2,虽然考虑了线程安全,但每次都要进入locker,即使instance对象已经赋值后
  3. 方案3,线程安全问题就没有考虑。
  • 适当的情况下可以选择方案4,方案5
  1. 方案4,使用“迫切”创建实例(当应用程序启动,初始化系统时,初始化全局变量时创建对象实例),而不用延迟实例化的方法
  2. 方案5,采用了延迟实例化的方法。
  • 注意混淆问题:

  不要和Monitor,ReaderWriterLockSlim等这些线程安全的使用方式混淆。

1.) Monitor:提供同步访问对象的机制。

2.) ReaderWriterLockSlim:表示用于管理资源访问的锁定状态,可实现多线程读取或进行独占式写入访问。

  • 点:

  1.)优点:

    a.)确保了系统中保存一个实例对象,为程序带来了开拓思路;

    b.)内存开销可能会占用一定空间,但它避免了每次都需要开辟空间的消费;

    c.)使得程序能逻辑清理,开发者可以单一的使用该实例对象去操作,而不别每次都要new一个实例对象来进行操作。

  2.缺点:

    a.)多个用户在操作这个对象时,线程的安全性,就需要考虑。

    b.)一直在占用资源,而不可以被回收。

 参考资料:《Head First 设计模式》

  欢迎拍砖!请牛人们给指点。

原文地址:https://www.cnblogs.com/yy3b2007com/p/4057300.html