GoF设计模式学习-单例模式

1.目的

控制实例的个数,类设计者应该保证只有一个实例,不能将此责任【只有一个实例】强制交给类使用者。

2.整体实现

1.单线程单例模式的实现。

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

namespace LearnDesignPattern
{
    public class Singleton
    {
        private Singleton() { }//构造函数私有化,使得用户无法通过new关键字创建对象
        private static Singleton instance;
        public static Singleton Instance
        {
            get
            {//懒加载模式,用户也可以每次获取的时候,都new,但是这样不推荐
                //首先判断,如果为第一次使用,则进行new
                if (instance == null)
                {
                    instance = new Singleton();
                }
                return instance;
            }
        }
        //注意【1】,C#的单例模式一般使用属性来获取Instance
        //而在Java,中一般使用public static Singleton getInstance()的方法,这点不同
        //注意【2】,为什么要使用Static关键字呢,我们知道Static的关键字的作用是
        //可以直接通过类名来进行调用,这样就保证了,需要先有类的实例才能获取
        //非static属性的情况
    }
}

2.多线程单例模式实现:

//如果两个线程同时判断instance是不是为空,当instance==null的时候
    //两个线程就同时创建出来实例,这样就存在了两个实例了
    public class Singleton
    {
       private Singleton() { }
        //volatile:被volatile修饰的变量的值,将不会被本地线程换缓存
        //所有对该变量的读写都是直接操作共享内存,从而确保多个线程能
        //正确的处理该变量
        private static volatile Singleton instance;
        //添加线程锁,确保只有一个线程可以访问该范围的代码,其他线程等待
        private static object objectLock = new object();
        public static Singleton Instance
        {
            //double check双重检查机制
            get
            {
                if (instance == null)
                {
                    lock (objectLock)
                    {
                        if (instance == null)
                        {
                            instance = new Singleton();
                        }
                    }
                }
                return instance;
            }
        }
    }

3.经典的多线程单例模式写法。

 //【使用静态构造器】
        //1.静态构造函数既没有访问修饰符,也没有参数
        //2.在创建第一个实例或引用任何静态成员之前,将自动调用静态构造函数来初始化类
        //3.无法直接调用静态构造函数
        //4.在程序中,用户无法控制何时执行静态构造函数
        //【保证1】保证使用类实例或者静态成员之前初始化
        //【保证2】懒加载,只有在第一次使用,才调用静态构造器
        //【保证3】.net框架会自动为多线程加锁
        public static readonly Singleton Instance = new Singleton();
        private Singleton() { }
        //【弊端】不支持参数化Singleton,因为传参必须使用方法来进行!!!GetInstance(object a,object b){}


4.参数化Singleton

//参数化Singleton
        private Singleton(int a,int b)
        {
            this.A = a;//A、B均为静态属性
            this.B = b;//A、B均为静态属性
        }
        public static Singleton GetInstance(int x, int y)
        {
            if (instance == null)
            {
                instance= new Singleton(x, y);
            }
            //可修改单例模式!就相当于修改当前单例的属性,并不会重新创建新的实例
            else
            {
                instance.A = x;//A、B均为静态属性
                instance.B = y;//A、B均为静态属性
            }
            return instance;
        }

3.思考

1.实例的个数可以两个么?三个......多个。使用时,一次创建多个,放在池子中,使用的时候去取。

2.如何将new构造器放到其他类中,实现局部使用一个对象的实例。

3.将new进行屏蔽,然后通过其他方法来实现new的效果【不仅仅是单例】。


 

 

posted on 2013-07-27 20:32  you Richer  阅读(185)  评论(0编辑  收藏  举报