概述:
单件模式的类图可以说是所有模式的类图中最简单的,事实上,它的类图上只有一个类。
尽管从设计的视角来说它很简单,但是实现上还是会遇到相当多的波折。
答:固然正确地实现单件模式需要一点技巧,但是阅读完这篇文章之后,你已经具备了用正确的方式实现单件模式的能力。当你需要控制实例个数时,还是应当使用单件模式。
答:如果你的类自给自足,而且不依赖于复杂的初始化,那么你可以这么做。但是,因为静态初始化的控制是在CLR受伤,这么做有可能导致混乱,特别是当有许多类牵涉其中的时候。这么做常常会造成一些微妙的,不容易发现的和初始uade次序有关的bug。除非你有绝对的必要使用类的单件,否则还是建议使用对象的单件
答:你说的是“一个类,一个责任”原则。没错,你似的对的,但见类不只负责管理自己的实例,并提供全局访问,还在应用程序中担当角色,所以也可以被视为是两个责任。尽管如此,由类管理自己的实例的做法并不少见。这可以让整体设计更简单。更何况,许多开发人员都已经熟悉了单件模式的这种做法。
答:继承单件类会遇到一个问题,就是构造器是私有的。你不能用私有构造器来扩展类。所以你必须把单件的构造器改成公共的或受保护的。但是这么一来就不算真正的单件了,因为别的类也可以实例化他。
如果你果真把构造器的访问权限改了,还有另一个问题出现,单件的实现是利用静态变量,直接继承会导致所有的派生类共享同一个实例变量,这可能不是你想要的。
答:在.net中,全局变量基本上就是对对象的静态引用。在这样的情况下使用全局变量会有一些缺点,我们已经提到了其中的一个:急切实例化VS延迟实例化。但是我们要记住这个模式的目的:确保类只有一个实例并提供全局访问,但是不能确保只有一个实例。全局变量也会变相鼓励开发人员,用许多全局变量指向许多小对象来造成这样的现象,但单件仍然可能被滥用。
如果没有一个全局变量引用单件模式的实例,该实例是否会被垃圾回收?
经过自己写代码的验证:不会被回收。
由下面的结果可知,两次调用GetInstance,只创建了一次Singleton实例
1.保证一个类有且仅有一个实例
2.且提供一个全局访问点
线程池(Thread Pool)/缓存(cache)/对话框/处理偏好设置和注册表的对象/日志对象/充当打印机/显卡等设备的驱动程序的对象。
1.考勤记录仪可以有多台,但是时钟必须只有一个,所有的考勤记录必须根据这个时钟来生成打卡时间记录。且该时钟是唯一的时间访问入口。
2.足球场上只能根据主裁判的手表来判断比赛进行了多长时间,比赛进行的时间是唯一的,
查看比赛进行的时间的访问入口时主裁判的手表上的时间。
我们可以用全局静态变量指向一个对象。程序员工作的时候约定好,只用这个全局变量作为唯一的一个访问这个对象的入口。
优点:
1.代码定义简单
2.调用方便
缺点:
1.程序员之间需要约定
2.程序一开始就得创建好对象,如果该对象非常耗资源,而程序执行的过程中又一直没有用到它,就形成了资源的浪费。
3.不能保证一个对象只能被实例化一次,如果程序员之间的约定并没有严格遵守,比如新来的同事并不知道有这个约定。
Singleton |
---|
Static uniqueInstance //其他有用的单件数据... |
Static GetInstance() |
//其他有用的单件方法... |