单例模式
设计模式简介
建筑设计大师Alexander在他的《建筑的永恒方法》一书中,是这样描述模式的:模式是一条由三个部分组成的通用规则,它表示了一个特定环境、一类问题和一个解决方案之间的关系。每一个模式描述了一个不断重复发生的问题,以及该问题解决方案的核心设计。
如果将这个描述推广到其它的工程设计领域,那么我们可以将软件开发领域中的设计模式(Design pattern)描述为:对处于特定环境下,经常出现的某类软件开发问题的一种相对成熟的设计方案。使用设计模式是为了重用代码,避免重复设计,让代码更容易被他人理解,保证代码可靠性。
所有纯文字的描述都是比较抽象的,所以我们举个现实中的例子,来帮助我们更好的理解设计模式。
假设我们要吃饭。现在桌子上已经摆好了饭菜,筷子和碗也摆好了,那我们如何把餐桌上的食物吃到我们的嘴里呢?很简单,拿起筷子把面前的饭菜夹起来然后送到我们的嘴里。这个过程,我们不用思考,就是自然而然的事情。可是,假如坐在饭桌前的是一位第一次来到中国的欧洲人,在这之前连见过筷子都没有,那么当他要吃饭的时候,他必须得仔细考虑一下,面前的这两根木棍是不是用来吃东西的,如果不是该用什么吃,如果是又该怎么用。
这个例子很简单,用筷子吃就相当于一种设计模式。吃饭是一个不断重复发生的问题,特别地,对中国人来说,用筷子吃是吃饭的一种解决方案,而且这种解决方案经过了时间地验证,已经演化成一种经验。
吃饭的经验告诉我们该如何吃饭。写代码的经验告诉我们该如何写代码,而设计模式就是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。
设计模式总共有 23 种。这些模式可以分为三大类:创建型模式(Creational Patterns)、结构型模式(Structural Patterns)、行为型模式(Behavioral Patterns)。除此之外,我们还应该了解J2EE 设计模式。
| 序号 | 模式 & 描述 | 包括 |
|---|---|---|
| 1 | 创建型模式 这些设计模式提供了一种在创建对象的同时隐藏创建逻辑的方式,而不是使用新的运算符直接实例化对象。这使得程序在判断针对某个给定实例需要创建哪些对象时更加灵活。 |
|
| 2 | 结构型模式 这些设计模式关注类和对象的组合。继承的概念被用来组合接口和定义组合对象获得新功能的方式。 |
|
| 3 | 行为型模式 这些设计模式特别关注对象之间的通信。 |
|
| 4 | J2EE 模式 这些设计模式特别关注表示层。这些模式是由 Sun Java Center 鉴定的。 |
|
单例模式
单例模式是最简单的一种设计模式之一。
如果一个类只能创建一个实例,则这个类被称为单例类,这种模式被称为单例模式。
单例类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
我们先看一下单例类的代码实现
package singleton; /** * Created by ASUS on 2017/4/3. */ public class Singleton { //使用一个类变量缓存曾经创建的实例 private static Singleton instance; //将构造器使用private修饰,隐藏该构造器 private Singleton(){} /**提供一个静态方法,用于返回Singleton实例。也只能通过该方法得到Singleton实例,因为构造器被隐藏了。 * 该方法可以加入自定义的控制,保证只产生一个Singleton对象. *getInstance() 方法中需要使用同步锁 synchronized (Singleton.class) 防止多线程同时进入造成 instance 被多次实例化。 * @return */ public static synchronized Singleton getInstance(){ //如果instance为null,表明还不曾创建Singleton对象 //如果instance不为null,则表明已经创建了Singleton对象,将不会执行该方法 if(instance == null){ instance = new Singleton(); } return instance; } }
下面是测试类
package singleton; import org.junit.Test; import static org.junit.Assert.*; /** * Created by ASUS on 2017/4/3. */ public class SingletonTest { @Test public void getInstance() throws Exception { //创建Singleton对象不能通过构造器,只能通过getInstance方法 Singleton s1 = Singleton.getInstance(); Singleton s2 = Singleton.getInstance(); System.out.println(s1==s2); } }
我们会看到控制台的输出:true
单例类的实现关键在于构造器私有,这样我们只能通过单例类的静态方法获取实例,而且这个实例是唯一的。
使用单例模式的优点在于:1.在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例。2.避免对资源的多重占用(比如写文件操作)。
当然,单例模式也有它的缺点,例如没有接口,不能继承,与单一职责原则冲突等。

浙公网安备 33010602011771号