设计模式(2)----- 单例模式

单例模式

问题:如何保证一个类只创建一个对象,且该对象全局共享

意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点

适用性:当类只有一个实例而且客户端可以从一个从所周知的访问点访问,当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展实例时。

总结:单例模式就是保证系统中一个类只有一个实例。也就是说只能自己new自己并且实例唯一并对外提供。

优点:

  1. 在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例。
  2. 避免对资源对过多占用。

缺点:

  1. 没有抽象层,不能继承扩展很难。
  2. 违背了“单一职责原则”,一个类只重视内部关系,而忽略外部关系。
  3. 不适用于变化对象。
  4. 滥用单例会出现一些负面问题,如为节省资源将数据库连接池对象设计为单例,可能会导致共享连接池对象对程序过多而出现连接池溢出。如果实例化的对象长时间不被利用,系统会认为是垃圾而被回收,这样将导致对象状态丢失。

解决方案【步骤】

  1. 创建一个类
  2. 定义一个私有的构造函数
  3. 定义一个私有静态的变量指向自己
  4. 定义一个公有静态的方法用于返回自己类的唯一实例

单例模式基本实现方式

1、饿汉模式

描述:这种方式比较常用,但容易产生垃圾对象。
优点:没有加锁,执行效率会提高。
缺点:类加载时就初始化,浪费内存。

using System;

public class Singleton
{
	//定义一个私有静态的变量指向自己
    private static Singleton _instance = new Singleton();
	//定义一个私有的构造函数
    private Singleton() { }
	//定义一个公有静态的方法用于返回自己类的唯一实例
    public static Singleton instance()
    {
        return _instance;
    }
}
2、懒汉模式(线程不安全)

描述:懒汉模式申明了一个静态对象,在用户第一次调用时初始化,虽然节约了资源,但第一次加载时需要实例化,反映稍慢一些,而且在多线程不能正常工作。

using System;

public class Singleton
{
    //定义一个私有静态的变量
    private static Singleton _instance;
    //定义一个私有的构造函数
    private Singleton() { }
    //定义一个公有静态的方法用于返回自己类的唯一实例
    public static Singleton instance()
    {
        if (_instance == null)
            _instance = new Singleton();
        return _instance;
    }
}
3、双重加锁机制

描述:这种方式采用双锁机制,安全且在多线程情况下能保持高性能。

using System;

public class Singleton
{
    //程序运行创建一个只读(readonly)的(object)进程辅助对象
    public static readonly object sync = new object();
    //定义一个私有静态的变量
    private static Singleton _instance;
    //定义一个私有的构造函数
    private Singleton() { }
    //定义一个公有静态的方法用于返回自己类的唯一实例
    public static Singleton instance()
    {
        //判断是否存在
        if (_instance == null)
        {
            //加锁  只有一个线程可以进入
            lock (sync)
            {
                if(_instance==null)
                    _instance = new Singleton();
            }
        }
        return _instance;
    }
}
静态初始化

描述:这种方式能达到双检锁方式一样的功效,但实现更简单。这种方式只适用于静态域的情况,双检锁方式可在实例域需要延迟初始化时使用。

using System;

public class Singleton
{
    //在第一次引用类的任何成员时创建实例,
    //公共语言运行库负责处理变量初始化
    private static readonly Singleton _instance = new Singleton();
    //定义一个私有的构造函数
    private Singleton() { }
    //定义一个公有静态的方法用于返回自己类的唯一实例
    public static Singleton instance()
    {
        return _instance;
    }
}
测试用例
using System;


class Program
{
    static void Main(string[] args)
    {
        //单例模式不能自己new自己
        //Singleton Obj = new Singleton();
        //获得唯一可用的对象
        Singleton obj = Singleton.instance();
        Singleton obj1 = Singleton.instance();
        //判断两个实例是否是同一实例
        Console.WriteLine(obj == obj1);
        Console.Read();
    }
}

在这里插入图片描述
设计模式------首页

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值