单例模式

设计模式简介

建筑设计大师Alexander在他的《建筑的永恒方法》一书中,是这样描述模式的:模式是一条由三个部分组成的通用规则,它表示了一个特定环境、一类问题和一个解决方案之间的关系。每一个模式描述了一个不断重复发生的问题,以及该问题解决方案的核心设计。

如果将这个描述推广到其它的工程设计领域,那么我们可以将软件开发领域中的设计模式(Design pattern)描述为:对处于特定环境下,经常出现的某类软件开发问题的一种相对成熟的设计方案。使用设计模式是为了重用代码,避免重复设计,让代码更容易被他人理解,保证代码可靠性。

所有纯文字的描述都是比较抽象的,所以我们举个现实中的例子,来帮助我们更好的理解设计模式。

假设我们要吃饭。现在桌子上已经摆好了饭菜,筷子和碗也摆好了,那我们如何把餐桌上的食物吃到我们的嘴里呢?很简单,拿起筷子把面前的饭菜夹起来然后送到我们的嘴里。这个过程,我们不用思考,就是自然而然的事情。可是,假如坐在饭桌前的是一位第一次来到中国的欧洲人,在这之前连见过筷子都没有,那么当他要吃饭的时候,他必须得仔细考虑一下,面前的这两根木棍是不是用来吃东西的,如果不是该用什么吃,如果是又该怎么用。

这个例子很简单,用筷子吃就相当于一种设计模式。吃饭是一个不断重复发生的问题,特别地,对中国人来说,用筷子吃是吃饭的一种解决方案,而且这种解决方案经过了时间地验证,已经演化成一种经验。

吃饭的经验告诉我们该如何吃饭。写代码的经验告诉我们该如何写代码,而设计模式就是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。

设计模式总共有 23 种。这些模式可以分为三大类:创建型模式(Creational Patterns)、结构型模式(Structural Patterns)、行为型模式(Behavioral Patterns)。除此之外,我们还应该了解J2EE 设计模式。

 

 

序号模式 & 描述包括
1 创建型模式
这些设计模式提供了一种在创建对象的同时隐藏创建逻辑的方式,而不是使用新的运算符直接实例化对象。这使得程序在判断针对某个给定实例需要创建哪些对象时更加灵活。
  • 工厂模式(Factory Pattern)
  • 抽象工厂模式(Abstract Factory Pattern)
  • 单例模式(Singleton Pattern)
  • 建造者模式(Builder Pattern)
  • 原型模式(Prototype Pattern)
2 结构型模式
这些设计模式关注类和对象的组合。继承的概念被用来组合接口和定义组合对象获得新功能的方式。
  • 适配器模式(Adapter Pattern)
  • 桥接模式(Bridge Pattern)
  • 过滤器模式(Filter、Criteria Pattern)
  • 组合模式(Composite Pattern)
  • 装饰器模式(Decorator Pattern)
  • 外观模式(Facade Pattern)
  • 享元模式(Flyweight Pattern)
  • 代理模式(Proxy Pattern)
3 行为型模式
这些设计模式特别关注对象之间的通信。
  • 责任链模式(Chain of Responsibility Pattern)
  • 命令模式(Command Pattern)
  • 解释器模式(Interpreter Pattern)
  • 迭代器模式(Iterator Pattern)
  • 中介者模式(Mediator Pattern)
  • 备忘录模式(Memento Pattern)
  • 观察者模式(Observer Pattern)
  • 状态模式(State Pattern)
  • 空对象模式(Null Object Pattern)
  • 策略模式(Strategy Pattern)
  • 模板模式(Template Pattern)
  • 访问者模式(Visitor Pattern)
4 J2EE 模式
这些设计模式特别关注表示层。这些模式是由 Sun Java Center 鉴定的。
  • MVC 模式(MVC Pattern)
  • 业务代表模式(Business Delegate Pattern)
  • 组合实体模式(Composite Entity Pattern)
  • 数据访问对象模式(Data Access Object Pattern)
  • 前端控制器模式(Front Controller Pattern)
  • 拦截过滤器模式(Intercepting Filter Pattern)
  • 服务定位器模式(Service Locator Pattern)
  • 传输对象模式(Transfer Object Pattern)

 

单例模式

单例模式是最简单的一种设计模式之一。

如果一个类只能创建一个实例,则这个类被称为单例类,这种模式被称为单例模式。

单例类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

我们先看一下单例类的代码实现

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.避免对资源的多重占用(比如写文件操作)。

当然,单例模式也有它的缺点,例如没有接口,不能继承,与单一职责原则冲突等。

 

posted @ 2017-04-05 14:22  thinker_zhao  阅读(275)  评论(0)    收藏  举报