设计模式系列:单例模式

一.名称

确保一个类只有一个实例,而且自行实例化,并向整个系统提供这个实例。
单例模式没有用到什么设计原则,更多的是一种封装的体现。

二.问题(为了解决什么问题)

  1. 要求生成唯一序列号的环境
  2. 在整个项目中需要一个共享访问点或共享数据,例如一个web页面上的计数器,可以不用把每次刷新都记录到数据库中,使用单例模式保持计数器的值,并确保是线程安全的
  3. 创建一个对象需要消耗的资源过多,如要访问io和数据库资源等
  4. 需要定义大量的静态常量和静态方法(如工具类)的环境,可以采用单例模式(当然,也可以直接声明为static的方式)。

三.解决方案(主要体现在uml和核心代码上)

单例的几种写法

1.饿汉式写法,线程安全

缺点:不能实现延迟加载

2.懒汉式写法,线程不安全

缺点:线程不安全

3.线程安全的单例:在getInstance方法上加同步

缺点:锁定的区域过大

4.线程安全的单例:双重检查锁定

5.线程安全的单例:静态内部类

这种比上面1、2都好一些,既实现了线程安全,又避免了同步带来的性能影响。

6.有上限的多例模式(来自设计模式之禅)

如果只需要一个对象,使用单例模式就可以了,但是如果要求一个类只能产生两三个对象呢是这里讲的这种模式。
假设现在有两个皇帝(其实,历史上也是有的,明朝历史上的土木堡事变),代码如下:

四.效果(有啥优缺点)

优点:
1. 单例对象在内存中只有一个,可以减少内存开支,不过在java中要注意垃圾回收机制的影响。
2. 单例模式提供了对唯一示例的受控访问。因为单例类封装了它的唯一实例,所以它可以严格控制客户怎样以及何时访问它。
3. 允许可变数目实例。

缺点:
1. 单例模式中没有抽象层,因此扩展困难,若要扩展,除非修改代码,基本上没有第二种途径。
2. 现在很多面对对象语言中都有垃圾回收机制,因此如果实例化的共享对象长时间不被使用,系统会认为他是垃圾,会自动销毁并回收资源,下次利用时又将重新实例化,这将导致共享的单例状态的丢失。

常见案例

windows系统中的任务管理器无论启动多少次,都是唯一的。

/p>

负载均衡器。xx公司承接了一个服务器负载均衡软件的开发工作,该软件运行在一台负载均衡服务器上,可以将并发访问和数据流量分发到服务器集群中的多台设备上进行并发处理,提高系统的整体处理能力,缩短响应时间。由于集群中的服务器需要动态删减,且客户端请求需要统一分发,因此需要确保负载均衡器的唯一性,即只能有一个负载均衡器来负责服务器的管理和请求的分发,否则将会带来服务器状态的不一致以及请求分配冲突等问题。

/p>

数据库连接池。xxx公司开发人员欲创建一个数据库连接池,将指定个数的(如2个或3个)数据库连接对象存储在连接池中,客户端代码可以从池中随机取一个连接对象来连接数据库。试通过对单例类进行改造,设计一个能够自行提供指定个数实例对象的数据库连接类。

来源:有心好书

声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2016年1月24日
下一篇 2016年1月24日

相关推荐