单件和工厂可能是设计模式中最基础,最好理解的部分了。下面说的是 .net  中一些单件模式中的东西。

单件模式是实现程序中只有一个某个类型的实例。最简单的代码应该如下:

 

using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{
    
class Class1
    
{
        
private Class1() { }

        
private static Class1 instance;
        
public static Class1 Instance
        
{
            
get
            
{
                
if (instance == null)
                
{
                    instance 
= new Class1();
                }

                
return instance;
            }

        }

    }

}

 

但是,这在多线程的情况下,还是有可能产生多个实例的。如有加个锁,可以防止产生多个实例:

 

using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{
    
class Class1
    
{
        
private Class1() { }

        
private static volatile Class1 instance;
        
private static object locker = new object();
        
public static Class1 Instance
        
{
            
get
            
{
                
if (instance == null)
                
{
                    
lock (locker)
                    
{
                        instance 
= new Class1();
                    }

                }

                
return instance;
            }

        }

    }

}



这里的 volatile 可以保证在多线程环境下,变量的值总是最新的。compiler 不会假定它是处于单线程访问环境下。

但是,这样写也有一点麻烦。看了 MSDN 的 Webcast 之后,人家给出了另一种方法:

 

using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{
    
class Class1
    
{
        
private Class1() { }

        
private static readonly Class1 instance = new Class1();
        
public static Class1 Instance
        
{
            
get
            
{
                
return instance;
            }

        }

    }

}



由于编译器只会以单线程使用静态构造函数,所以这样做可以保证在多线程下的安全性。

如果要实现参数化的单件模式,上面的 readonly 方法做起来会有一点麻烦。下面是 readonly 方法下的参数化单件模式的实现:

 

using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication1
{
    
class Class1
    
{
        
private Class1() { }

        
private string str = "";
        
private static readonly Class1 instance = new Class1();

        
public static Class1 GetInstance(string s)
        
{
            instance.Initialize(s);
            
return instance;
        }


        
private void Initialize(string s)
        
{
            
this.str = s;
        }

    }

}

当然还可以用私有的参数化构造函数来做,效果一样。如果用 lock 的话,代码量无疑会多一些。webcast 的讲师说得对,简单就是美