设计模式二-----单件模式

本文详细介绍了设计模式中的单件模式,包括实现单件模式的内外部方式、多线程问题的处理、粗细粒度的考量以及分布环境下的应用。强调了单件模式在控制实例数量和保证一致性上的作用,并探讨了其在长时间运行程序和分布式环境中的挑战与解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

设计模式二-----单件模式

​ 单件模式的主要用途在于控制某个类型的实例数量–有且仅有一个,例如与统计相关业务需求实现。(单件模式的主要意图就是控制该类只能够创建一个实例,同时向客户程序提供唯一访问它的全局访问点)

​ 试图通过经典单件模式实现分布式环境下的“单件”不现实,因此,项目中的“单”字是有上下文和语义范围限制

在这里插入图片描述

一、实现单件的方式

外部方式:
​ 客户程序使用某些全局对象时,做一些Try-Use的工作;
​ 如果没有,就自己创建一个,把它放在全局位置上;
​ 如果原本有,就直接用一个现成的。

内部方式:
​ 类型自己控制生成实例的数量,无论客户程序是否Try过,类型自己控制就提供一个实例,客户程序使用的都是这个现成的唯一的实例

​ 相比较而言,外部方式很不可靠,毕竟实例不只是一个,同时也不能做到全部的客户程序都做这种唯一性的检查。内部方式把干扰因素排除在类型之外,相对更保险一些

二、多线程问题

值得注意的问题是单件模式遇到多线程调用问题
​ 1、可以添加关键字(volatilc,表示字段可能被多个线程修改,但是不接受编译器优化,也就是说在任何时间访问读是一个值)
​ 2、在调用前提升变量范围的方式解决
​ 3、实例构造函数私有化,公共静态成员访问

代码细节问题
​ 1、不要实现ICloeable接口或者继承自其相关的子类,否则客户程序可以跳过已经隐藏的类构造函数
​ 2、严防序列化,因为序列化事实上完成了Singleton对象的复制和重现

三、粗细粒度的单件模式

​ 除了线程安全外,还需要注意单件模式的粗细粒度问题。例如某个线程是长时间运行的后台任务,他本身存在很多模块和中间块处理,但每个线程都希望有自己的线程内单独Singleton对象,其他线程也独立操作自己的线程内Singleton,这样Singleton的实例总数 = 1(每个线程内部唯一一个) * N (线程数) = N。

​ 另外,需要注意桌面应用和Web应用中粗细粒度问题,实际问题需要适应的方法。

四、分布环境下的单件模式

​ 除了限制在一个进程内,软件性能可以进一步提升,很多关键应用都需要到集群实现水平扩展。

​ 之前在一个线程内部,为了实现一个线程安全的唯一实例就需要大费周章地做一个Double Check或取巧地采用》NET Framework内置机制。

​ 当2个以上内部都保存一个具有new Singleton()能力的类型后,常规的单件模式很难控制他们的实现,这时直接剥夺他们new Singleton()的能力,双方之间增加一个代理,由这个代理向本进程内部的实体提供远程Singleton实例的引用,把构造工作从本地剥离到远程。

​ 如果是Cluster环境,远程调用可能运行在集群的Controller节点上,也可以运行在某个Controller+Member的机器上;如果仅仅是一台机器的多个进程间通信,它可以“寄生”在某个进程独立内部,或者自己在一个单独的进程里。

​ 另外,还有一个班Singleton的方式,内涵上单件模式要求的“唯一性”是为了内容的统一一致,既要确保所有关于某些内容的修改是同步的。因为如果内容自己是能“同步”的,那么是最好的。

五、单件模式的使用问题

​ 经典单件模式实现上总是会在内存中保留一个一致驻留内存的实例,尽管这也是模式意图所在,但这往往不适合那些需要长时间持续运行的程序,因为变化总是存在,对它的任何修改都需要重启进程。

​ 为了避免这个问题,可以根据需要为单件对象增加一个维护方法,允许外部程序或者工具调整单件对象成员;也可以设计一个Timer,赋予其自维护性。

​ 同时,单件对象的存在多少也会程序的扩展性受到一定程度的限制。

六、小结

​ 单件模式更多地强调构造数量的唯一性。

​ 工程上实现Singleton的挑战主要来自于它的运行环境和需要保持Singleton特质的颗粒度,为了降低技术实施风险可以借助数据库、共享进程等方式近似解决分布式环境下Singleton的实现。

leton特质的颗粒度,为了降低技术实施风险可以借助数据库、共享进程等方式近似解决分布式环境下Singleton的实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值