单例模式-HeadFirst学习

一、需求背景

有些类在实际应用场景中只需要一个具体对象来管理,如线程池(threadpool)、缓存(cache)、对话框、处理偏好设置和注册表的对象、日志对象、充当打印机、显卡等设备的驱动程序的对象。事实上这类对象只能有一个实例,如果制造出多个实例,就会导致很多问题产生,如程序的行为异常、资源使用过量,或者不一致的结果。

单例模式的作用相当于全局变量,但全局变量必须在程序一开始就创建好对象,一但当前对象很耗费资源,而当前数据未实际用到这个对象,就有些浪费。

二、实现要点

1、必须将构造函数定义为private的,禁止外部直接调用构造函数,这样就只能走全局访问点来这样一条路径来获取当前类对象;

2、需要定义一个静态类成员变量,在第一次外部访问类对象时构建,以后再获取,直接使用,直到程序声明周期结束;

3、需要定义一个public的静态方法作为获取类对象的方法;

三、存在问题

全局访问点方法实现过程中会遇到多线程问题,导致设计模式初期预想的效果会失效;

三、例子代码

namespace ChocolateBoilerCleanWater
{
    /// <summary>
    /// 巧克力工厂---原始类
    /// </summary>
    public class ChocolateBoiler
    {
        private bool empty;
        private bool boiled;

        /// <summary>
        /// 构造函数改为私有,禁止外部直接创建对象
        /// </summary>
        public ChocolateBoiler()
        {
            empty = true;
            boiled = false;
        }

        public bool isEmpty()
        {
            return empty;
        }

        public bool isBoiled()
        {
            return boiled;
        }

        public void fill()
        {
            if (empty)
            {
                empty = false;
                boiled = false;
            }
        }

        public void drain()
        {
            if (!isEmpty() && isBoiled())
            {
                empty = true;
                boiled = false;
            }
        }

        public void boil()
        {
            if (!isEmpty() && !isBoiled())
            {
                boiled = true;
            }
        }
    }
}

namespace ChocolateBoilerSingleton
{
    /// <summary>
    /// 巧克力工厂-单例模式的初次实现
    /// </summary>
    public class ChocolateBoiler
    {
        private bool empty;
        private bool boiled;

        private static ChocolateBoiler m_ChocolateBoiler;

        /// <summary>
        /// 定义全局唯一访问点
        /// </summary>
        /// <returns></returns>
        public static ChocolateBoiler getInstance()
        {
            if(null == m_ChocolateBoiler)
                m_ChocolateBoiler = new ChocolateBoiler();

            return m_ChocolateBoiler;
        }

        /// <summary>
        /// 构造函数改为私有,禁止外部直接创建对象
        /// </summary>
        private ChocolateBoiler()
        {
            empty = true;
            boiled = false;
        }

        public bool isEmpty()
        {
            return empty;
        }

        public bool isBoiled()
        {
            return boiled;
        }

        public void fill()
        {
            if (empty)
            {
                empty = false;
                boiled = false;
            }
        }

        public void drain()
        {
            if (!isEmpty() && isBoiled())
            {
                empty = true;
                boiled = false;
            }
        }

        public void boil()
        {
            if (!isEmpty() && !isBoiled())
            {
                boiled = true;
            }
        }
    }
}

namespace ChocolateBoilerSingletonConsiderMultiThread
{
    /// <summary>
    /// 巧克力工厂--考虑多线程的单例模式实现
    /// </summary>
    public class ChocolateBoiler
    {
        private bool empty;
        private bool boiled;

        private static object _lock = new object();
        private static ChocolateBoiler m_ChocolateBoiler;

        /// <summary>
        /// 定义全局唯一访问点
        /// </summary>
        /// <returns></returns>
        public static  ChocolateBoiler getInstance()
        {
            if (null == m_ChocolateBoiler)
            {
                lock (_lock)
                {
                    if (null == m_ChocolateBoiler)
                    {
                        m_ChocolateBoiler = new ChocolateBoiler();
                    }
                }
            }
            return m_ChocolateBoiler;
        }

        /// <summary>
        /// 构造函数改为私有,禁止外部直接创建对象
        /// </summary>
        private ChocolateBoiler()
        {
            empty = true;
            boiled = false;
        }

        public bool isEmpty()
        {
            return empty;
        }

        public bool isBoiled()
        {
            return boiled;
        }

        public void fill()
        {
            if (empty)
            {
                empty = false;
                boiled = false;
            }
        }

        public void drain()
        {
            if (!isEmpty() && isBoiled())
            {
                empty = true;
                boiled = false;
            }
        }

        public void boil()
        {
            if (!isEmpty() && !isBoiled())
            {
                boiled = true;
            }
        }
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值