C# & Unity 面向对象补全计划 之 单例模式
创始人
2024-11-10 00:07:34

本文仅作学习笔记与交流,不作任何商业用途,作者能力有限,如有不足还请斧正
本系列作为七大原则和设计模式的进阶知识,看不懂没关系

了解我的专栏C#面向对象与进阶:http://t.csdnimg.cn/mIitr,尤其是关于类的那篇文章即可,另外尤其需要注意的点就是,类的成员属性可以get和set类对象,只是很少这么举例

首先,单例模式可以理解为只有一个外部访问口的类,是在类的概念上设计的

1.单例模式介绍

      单例模式是一种创建型设计模式,确保一个类只有一个实例,并提供一个全局访问点来访问这个实例,它在需要控制资源的访问或确保某些操作只执行一次的场景中非常有用

  也就是说,单例模式不能在类外部去创建新实例,就是不能"new"

特点

分类

一级分类

根据实例创建的时刻分类,可以理解为一级分类

二级分类 

根据优缺点分类,可以理解为建立在一级分类上的二级分类

静态变量初始化:这是饿汉式(Eager Initialization),因为实例在类加载时就已经创建

双重检查锁定:这是懒汉式(Lazy Initialization),因为实例是在第一次需要时才创建,并且通过双重检查锁定来确保线程安全

Lazy:这是懒汉式(Lazy Initialization),因为实例是在第一次需要时才创建,并且使用了 Lazy 类来确保线程安全和延迟加载

2.举栗子

说那么多分类,其实会写会用就行,哪那么多弯弯绕绕的,又不是去考研

 静态变量初始化

注意,实例已经在类中被创建,所以叫饿汉=迫不及待需求对象

// 静态变量初始化 A a = A.Instance; a.func();  public class A  {     //单例模式     //1.私有构造函数     private A() { }     //2.私有静态唯一实例     private static A instance = new A();     //3.唯一对外开放的公共属性     public static A Instance => instance;      public void func() {         Console.WriteLine("这是一个单例模式");     } }

优化方面: 可以设置密封类,并对唯一实例设置为只读状态

sealed 
readonly 

双重检查锁定

        要想实现,懒汉式=对象需要的时候才创建一个,需要objcet的帮忙,其实总的来讲就比静态变量初始化多出一个静态字段和双重锁的逻辑

public class A {     //1.私有静态字段     private static A instance = null;     //2.私有唯一实例,但是这个实例是objcet的     private static object obj = new object();     //3.私有构造函数     private A() {     }     //4.唯一对外开放的公共属性     public static A Instance {         get {             if (instance == null) {                 lock (obj) {                     if (instance == null) {                         instance = new A();                     }                 }             }             return instance;         }     } }

Lazy

        看到这个大大的T了没有,就是本质上就是泛型类

B b = A.Instance; b.Func(); public class A //where T :new() ()=>new()     {     //1.私有静态唯一实例     private static Lazy instance = new Lazy();     //2.公共外部属性     public static T Instance => instance.Value;     //3.私有构造函数     private A() { } } public class B     {      public void Func()         {         Console.WriteLine("单例模式的使用");      } }

Q.为什么是instance.Value而不是instance?

A: 因为泛型T的原因,导致instance像是一个对象盒子,而不是属性Instance需要返回的盒子里面的东西

进阶版本:

public class A where T :new()      {     //1.私有静态唯一实例     private static Lazy instance = new Lazy(() => new());     //2.公共外部属性     public static T Instance => instance.Value;     //3.私有构造函数     private A() { } }

相关内容

热门资讯

裸辞做“一人公司”,我后悔了 去年这个时候,一位以色列程序员正在东南亚旅行。他顺手把一个在脑子里转了很久的想法做成了产品,一个让任...
南京建成国内首个Pre-6G试... 4月21日,2026全球6G技术与产业生态大会在南京开幕。全息互动技术展台前,一名远在北京的工作人员...
超梵求职受邀参加“2025抖音... 超梵求职受邀参加“2025抖音巨量引擎成人教育行业生态大会”,探讨分享优质内容传播,服务万千学员。 ...
摩托罗拉Razr 2026(R... IT之家 4 月 22 日消息,摩托罗拉宣布新一代 Razr 折叠手机将于 4 月 29 日在美国发...
库克卸任,特纳斯领航:苹果新纪... 苹果首席执行官蒂姆·库克将卸任,硬件工程主管约翰·特纳斯将接任,苹果公司今天宣布此事。 库克将在夏季...