写点什么

单例模式的实现方式

发布于: 2020 年 06 月 24 日
单例模式的实现方式

一、单例相关


很多时候我们在处理业务的时候需要一个公用的对象,单例基本就是首选。但是 web 容器天然的多线程的,所以创建单例对象的时候还是需要稍微注意一下,下面是几种创建模式:


第一种:


上面的方式就是私有化构造方法,这样就防止了通过 new 这种方式创建对象,另外定义一个当前对象的一个私有静态的自己,并且提供了一个 public 的静态方法作为访问的入口,所以一旦应用运行起来,就不会再存在另外一个当前类的实例化对象。static 修饰的属性,线程间可见。


第二种:


第二张图是另外一中实现方式,第一种实现方式是一开始就实例化了 instance(分配了内存空间)。第二张图初始值为 null,当真正需要的时候再实例化。上面说过 static 修饰的成员变量是线程间可见的,如果第一个和第二个线程在调用 getinstance 的时候都判断 installce 为 null,那么就会实例化两次。所以咱得加上 sync 来确保只有一次实例化。但是 sync 的锁会造成额外的开销,所以两个各有优劣。


第三种:

public class Sigleton{	private Sigleton(){}	private static Sigleton instance = null;
public static Sigleton getInstance(){ if(instance == null){ Synchronized(Sigleton.class){ if(instance == null){ instance = new Sigleton(); } } } return instance; }}
复制代码


这种方式能在一定程度上减少对 synchronize 的使用,属于第二中方式的优化。


第四种:使用枚举,枚举天然就满足单例的使用场景。


总结:这里还有些其他的技巧来创建单例,但是都可以理解为上面的变种。知道上面的几种方式就够了,另外要代码更优雅的话,多用枚举。


二、组合模式打印窗口

这个问题有多种实现方式,简单的方式可以简单的用一个类即可实现:



说明:如果抽象所有的元素都是 container 即可,叶子节点也可以理解为没有子容器的容器节点。运行代码及结果展示:


也可以把 container 设计成一个抽象类:


定义每一个容器:


编排容器关系:


结果:


优化一点的做法:


发布于: 2020 年 06 月 24 日阅读数: 61
用户头像

还未添加个人签名 2018.03.31 加入

还未添加个人简介

评论

发布
暂无评论
单例模式的实现方式