.NET2.0设计模式 (.NET 2.0 Patterns) 1 -- 单件模式(Sington Patterns)

为什么要使用单件模式(Why use Singleton pattern)

      我以前开发过一个OA系统,里面有个工作流子系统。工作流是一个很复杂的系统,采用CS架构开发最好了,但是现在要采用BS架构。BS架构对状态的处理是一个弱点。这个任务流系统需要实现任务流自定义,就是用户可以设计一个流程。谁执行,谁审核,通知谁都是自定义的。那么在定义这个流程的时候不可能一个页面就定义完,需要在多个页面之间传递数据。我们最先想到的办法就是采用Session或者Application。但是它们的不稳定性,他们的会释放都是让人头疼的。还有一个问题,如果系统运行了很久,一个企业每天都有很多工作流需要处理,那么工作流这个表的数据就是近百万条,而查找、修改工作流需要跨多个表的查询操作。并发多的时候难免造成数据库服务器死锁或者Down机。这个时候我就想起了CS架构的程序,所有的对象都不释放,随时可以访问,可以启动一个线程,选择一个合适的时机进行数据库读写。而BS架构很难做到。

      那么采用BS架构就无法有效的保存状态了吗?答案是肯定可以。将我们原来的CS架构的工作流系统拿过来,编写全局的唯一的对象将整个系统运行起来。那么整个系统就是用这个全局的唯一的标识符来访问,他不会因为Web页面的释放而释放。说白了就是采用了单件模式。

      真实世界里有很多单件模式,比如一说中国,肯定是说亚洲洲的中国,世界上只有一个中国,因此中国就是一个单件模式的例子。

什么是单件模式(What is Singleton pattern)

      单件模式(Singleton Patterns)顾名思义就是一个类只有一个实例。也就是世界上只有一个中国,中国就是唯一的实例。这个事例可以有多个引用,比如说“China”可以引用中国,“中国”也可以引用中国。

如何实现单件模式(How to use Singleton pattern)

      1、UML图

 

      2、C#代码

        2.1普通实现,首先将类的构造函数声明成私有的,然后生命一个静态的引用。这就是最简单的单件模式。

 

 

     ///   <summary>
    
///  单件模式,线程不安全
    
///   </summary>
     public   class  Singleton1
    {
        
///   <summary>
        
///  构造函数私有防止被外界实例化
        
///   </summary>
         private  Singleton1()
        { }

        
private   static  Singleton1 _Instance;
        
///   <summary>
        
///  先判断字段是否为空,然后实例化或者返回
        
///   </summary>
         public   static  Singleton1 Instance
        {
            
get  
            {
                
if  (_Instance  ==   null )
                {
                    _Instance 
=   new  Singleton1();
                }
                
return  Singleton1._Instance; 
            }
            
set
            {
                Singleton1._Instance 
=  value; 
            }
        }
    }

 

          看过了上面的代码,能发现有什么问题呢?那就是线程不安全,当地多个线程同时执行if (_Instance == null)语句的时候,都会new一个新对象,这样就不能保证是单件。

          那么下面就是线程安全的单件模式

       2.2线程安全但是惰性

     ///   <summary>
    
///  单件模式,线程安全,但是惰性的
    
///   </summary>
     public   class  Singleton2
    {
        
private  Singleton2()
        { }
        
///   <summary>
        
///  直接实例化
        
///   </summary>
         private   static  Singleton2 _Instance  =   new  Singleton2();
        
///   <summary>
        
///  
        
///   </summary>
         public   static  Singleton2 Instance
        {
            
get  
            {
                
return  Singleton2._Instance; 
            }
            
set
            {
                Singleton2._Instance 
=  value; 
            }
        }
    }

 

      从上面的代码,可以看到,private static Singleton2 _Instance = new Singleton2();不论使用不使用该对象,这一句代码一定要执行的。因此我们说这种实现是惰性的。如果我们想采用不惰性的实现,请看下面的代码

      2.3线程安全不惰性

     public   class  Singleton3
    {
        
private  Singleton3()
        { }
        
private   static  Singleton3 _Instance;
        
///   <summary>
        
///  由于在.NET中无法锁定空对象因在这里声明一个对象专门为了锁
        
///   </summary>
         private   static   object  _TheLock;

        
public   static  Singleton3 Instance
        {
            
get
            {
                
// 首先判断单件是不是空
                 if  (_Instance  ==   null )
                {
                    
// 锁定
                     lock  (_TheLock)
                    {
                        
// 再次判断,请思考为什么要再次判断呢?
                         if  (_Instance  ==   null )
                        {
                            _Instance 
=   new  Singleton3();
                        }
                    }
                }
                
return  Singleton3._Instance; 
            }
            
set
            {
                Singleton3._Instance 
=  value; 
            }
        }

    }

       为什么要判断两次才行呢?在.NET环境下,不能锁定空对象。因此我们需要一个辅助对象来实现锁功能。但是锁住的对象不是我们需要的对象,因此要判断两次。

在什么场合使用单件模式(Where can use Singleton pattern)

      单件模式的应用场合太多了。本人只能在这里发表一些愚见。根据我的开发经验,单件模式一般使用在根对象上。比如我写一个Word,那么表示Word应用程序的根对象采用单件模式。编写一个WindowsService,这个这个服务用一个对象管理起来,这个对象采用单件模式。

      几点思考

      1、单键模式就是类只有一个实例,不是说整个系统里就一个实例,在.NET环境下表示一个应用程序域内就一个对象。

      2、您可以写一个单件模式的类,部署在两个应用程序中,一个控制台的。一个Winforms的,修改一个对象的值,您可以发现连个应用程序中的对象不是一个。

源码下载(Download code)

下载

返回目录

转载于:https://www.cnblogs.com/michael555cdj/archive/2009/01/04/1368463.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值