继承实现单例模式的探索(二)
前言
本篇文章继续探索通过继承实现单例模式的可行方案,这次的方案将采用反射机制隐式创建派生类实例,示例代码为C#。
代码
v1.0
using System.Reflection;/// <summary>
/// 单例模式基类
/// </summary>
/// <typeparam name="T">单例类型</typeparam>
public abstract class Singleton<T>
where T : class
{public static T instance => _instance.Value;static readonly Lazy<T> _instance = new Lazy<T>(Create);#pragma warning disable CS8603static T Create(){return Activator.CreateInstance(typeof(T),BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance,null, null, null) as T;}
#pragma warning restore CS8603
}
测试
单例模式基类
/// <summary>
/// 单例模式基类
/// </summary>
/// <typeparam name="T">单例类型</typeparam>
public abstract class SingletonWithTest<T>
where T : class
{public static T instance => _instance.Value;static readonly Lazy<T> _instance = new Lazy<T>(Create);#pragma warning disable CS8603static T Create(){return Activator.CreateInstance(typeof(T),BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance,null, null, null) as T;}
#pragma warning restore CS8603
}
派生类
public class TestA : SingletonWithTest<TestA>
{public readonly string key;TestA() { key = "Default A"; }
}public class TestB : SingletonWithTest<TestB>
{public readonly string key;public TestB() { key = "Default B"; }
}public class TestC : SingletonWithTest<TestC>
{public readonly string key;public TestC(string key) { this.key = key; }
}public class TestD : SingletonWithTest<TestD>
{public readonly string key;public TestD() { key = "Default D"; }public TestD(string key) { this.key = key; }
}public class TestE : SingletonWithTest<TestE>
{public readonly string key;TestE() { key = "Default E"; }public TestE(string key) { this.key = key; }
}public class TestF : SingletonWithTest<TestF>
{public readonly string key = "Default F";
}
测试代码
// ********************************* 线程安全测试:通过 *********************************Thread t1, t2, t3, t4, t5, t6;// 打印同一单例的 HashCode 测试:通过
// t1 = new Thread(() => Console.WriteLine("Thread1:" + TestA.instance.GetHashCode()));
// t2 = new Thread(() => Console.WriteLine("Thread2:" + TestA.instance.GetHashCode()));
// t3 = new Thread(() => Console.WriteLine("Thread3:" + TestA.instance.GetHashCode()));
// t4 = new Thread(() => Console.WriteLine("Thread4:" + TestA.instance.GetHashCode()));
// t5 = new Thread(() => Console.WriteLine("Thread5:" + TestA.instance.GetHashCode()));
// t6 = new Thread(() => Console.WriteLine("Thread6:" + TestA.instance.GetHashCode()));// 同时使用不同单例的测试:通过
t1 = new Thread(() => Console.WriteLine("Thread1:" + TestA.instance.GetHashCode()));
t2 = new Thread(() => Console.WriteLine("Thread2:" + TestB.instance.GetHashCode()));
t3 = new Thread(() => Console.WriteLine("Thread3:" + TestC.instance.GetHashCode())); // 没有无参构造函数,触发异常
t4 = new Thread(() => Console.WriteLine("Thread4:" + TestD.instance.GetHashCode()));
t5 = new Thread(() => Console.WriteLine("Thread5:" + TestE.instance.GetHashCode()));
t6 = new Thread(() => Console.WriteLine("Thread6:" + TestF.instance.GetHashCode()));t1.Start();
t2.Start();
t3.Start();
t4.Start();
t5.Start();
t6.Start();t1.Join();
t2.Join();
t3.Join();
t4.Join();
t5.Join();
t6.Join();
优缺点分析
| 优点 | 1.继承实现单例模式; 2.按需加载,延迟初始化; 3.线程安全; 4.可以通过单例基类规范统一标准; 5.派生类的无参构造函数用于初始化; 6.将派生类实例创建权限交由派生类本身决定,通常,为遵循单例模式的原则应向外部关闭通过new关键字显式调用构造函数的权限,但这对派生类而言并非硬性要求; |
|---|---|
| 缺点 | 1.反射开销; 2.派生类必须具备无参构造函数,且无参构造函数需要向单例基类提供可进行反射访问的权限; |
版本改进
......
系列文章
继承实现单例模式的探索(一)
如果这篇文章对你有帮助,请给作者点个赞吧!
相关文章:
继承实现单例模式的探索(二)
前言 本篇文章继续探索通过继承实现单例模式的可行方案,这次的方案将采用反射机制隐式创建派生类实例,示例代码为C#。 代码 v1.0 using System.Reflection;/// <summary> /// 单例模式基类 /// </summary> /// <typeparam name"T&…...
设计模式-访问者模式
访问者模式(Visitor):表示一个作用于某对象结构中的各元素的操作,使得在不改变个元素的类的前提下定义作用于这些元素的新操作。...
国创——基于Unity3D和MediaPipe构建虚拟人物驱动系统
以下是一个基于Unity3D和MediaPipe构建虚拟人物驱动系统的基本概念和简化的Python示例代码框架。请注意,这只是一个基础示例,实际应用中可能需要更多的完善和调整。 一、整体概念 1. MediaPipe - MediaPipe是一个用于构建多模态(例如视频、…...
环境可靠性
一、基础知识 1.1 可靠性定义 可靠性是指产品在规定的条件下、在规定的时间内完成规定的功能的能力。 可靠性的三大要素:耐久性、可维修性、设计可靠性 耐久性:指的是产品能够持续使用而不会故障的特性,或者说是产品的使用寿命。 可维修性&a…...
Chromium 设置页面打开系统代理源码分析c++
1、前端页面调用showProxySettings() {chrome.send("showProxySettings")} 2、c 响应代码如下 chrome\browser\ui\webui\settings\system_handler.ccvoid SystemHandler::RegisterMessages() {web_ui()->RegisterMessageCallback("showProxySettings",b…...
信号检测理论(Signal Detection Theory, SDT)
信号检测理论(Signal Detection Theory, SDT)模拟是一种实验设计,用于研究和理解在存在噪声或不确定性的情况下如何做出决策。在心理学、认知科学、工程学和许多其他领域,信号检测理论都非常重要。 一、基础概念: 在信…...
Flink源码剖析
写在前面 最近一段时间都没有更新博客了,原因有点离谱,在实现flink的两阶段提交的时候,每次执行自定义的notifyCheckpointComplete时候,好像就会停止消费数据,完成notifyComplete后再消费数据;基于上述原因…...
[Python学习日记-39] 闭包是个什么东西?
[Python学习日记-39] 闭包是个什么东西? 简介 闭包现象 闭包意义与作用 简介 在前面讲函数和作用域的时候应该提到过,当函数运行结束后会由 Python 解释器自带的垃圾回收机制回收函数内作用域已经废弃掉的变量,但是在 Python 当中还有一种…...
XSLT 实例:掌握 XML 转换的艺术
XSLT 实例:掌握 XML 转换的艺术 引言 XSLT(可扩展样式表语言转换)是一种强大的工具,用于将 XML(可扩展标记语言)文档转换为其他格式,如 HTML、PDF 或纯文本。在本文中,我们将通过一…...
【C++】第一节:C++入门
1、C关键字 2、命名空间 在C/C中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称将都存在于全局作用域中,可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染&am…...
CSP-S 2021 T1廊桥分配
CSP-S 2021 T1廊桥分配 枚举分配给国内航班和国外航班的廊桥数量,若分配给国内机场 i i i个廊桥,则国外机场就有 n − i n-i n−i个廊桥,在此基础上分别判断两边各能通过多少飞机。用一个小根堆存储飞机离开的时间,枚举到一个飞机…...
项目配置说明
文章目录 一、下载 vscode 并安装相应扩展1.1 下载 vscode1.2 安装扩展 二、git 项目三、git 提交流程3.1 确定要提交的代码 四、git 拉新流程 一、下载 vscode 并安装相应扩展 1.1 下载 vscode vscode 我已经发群里了,或者自己去官网下载也行 1.2 安装扩展 打开…...
linux网络编程实战
前言 之前找工作的之后写了一些网络编程的笔记和代码,然后现在放到csdn上保存一下。有几个版本的,看看就好。就是简单的实现一下服务端和客户端之间的交互的,还没有我之前上linux编程课写的代码复杂。 哦对了,这个网络编程的代码对…...
网络基础 【HTTP】
💓博主CSDN主页:麻辣韭菜💓 ⏩专栏分类:Linux初窥门径⏪ 🚚代码仓库:Linux代码练习🚚 💻操作环境: CentOS 7.6 华为云远程服务器 🌹关注我🫵带你学习更多Linux知识…...
[Linux#61][UDP] port | netstat | udp缓冲区 | stm32
目录 0. 预备知识 1. 端口号的划分范围 2. 认识知名端口号 3. netstat 命令 4. pidof 命令 二.UDP 0.协议的学习思路 1. UDP 协议报文格式 报头与端口映射: 2. UDP 的特点 面向数据报: 3. UDP 的缓冲区 4. UDP 使用注意事项 5. 基于 UDP 的…...
定义类方法的错误总结
struct Renderer {vector<function<void(vector<string>)>> fileDropListeners;// 定义一个方法,它是将一个函数作为输入,callback是形参void print(function<void(float)> callback_func);void onFileDrop(function<void(ve…...
Redis --- 第三讲 --- 通用命令
一、get和set命令 Redis中最核心的两个命令 get 根据key来取value set 把key和value存储进去 redis是按照键值对的方式存储数据的。必须要先进入到redis客户端。 语法 set key value : key和value都是字符串。 对于上述这里的key value 不需要加上引号&#…...
【Linux】进程间关系与守护进程
超出能力之外的事, 如果永远不去做, 那你就永远无法进步。 --- 乌龟大师 《功夫熊猫》--- 进程间关系与守护进程 1 进程组2 会话3 控制终端4 作业控制5 守护进程 1 进程组 之前我们提到了进程的概念, 其实每一个进程除了有一个进程 ID(P…...
【可视化大屏】将柱状图引入到html页面中
到这里还是用的死数据,先将柱状图引入html页面测试一下 根据上一步echarts的使用步骤,引入echarts.js后需要初始化一个实例对象,所以新建一个index.js文件来进行创建实例化对象和配置数据信息等。 //在index.html引入<script src"j…...
gm/ID设计方法学习笔记(一)
前言:为什么需要gm/id (一)主流设计方法往往侧重于强反型区(过驱>0.2V),低功耗设计则侧重于弱反型区(<0),但现在缺乏对中反型区的简单和准确的手算模型。 1.对于…...
基于FPGA的PID算法学习———实现PID比例控制算法
基于FPGA的PID算法学习 前言一、PID算法分析二、PID仿真分析1. PID代码2.PI代码3.P代码4.顶层5.测试文件6.仿真波形 总结 前言 学习内容:参考网站: PID算法控制 PID即:Proportional(比例)、Integral(积分&…...
css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...
C++中string流知识详解和示例
一、概览与类体系 C 提供三种基于内存字符串的流,定义在 <sstream> 中: std::istringstream:输入流,从已有字符串中读取并解析。std::ostringstream:输出流,向内部缓冲区写入内容,最终取…...
零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
SpringCloudGateway 自定义局部过滤器
场景: 将所有请求转化为同一路径请求(方便穿网配置)在请求头内标识原来路径,然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...
Caliper 配置文件解析:config.yaml
Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...
C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。
1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj,再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...
