23种设计模式

来源:互联网 发布:淘宝吧 编辑:程序博客网 时间:2024/06/07 12:25

一、设计模式的分类

总体来说设计模式分为三大类:

创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。

结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。

行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

其实还有两类:并发型模式和线程池模式。用一个图片来整体描述一下:



单例模式(Singleton

单例对象(Singleton)是一种常用的设计模式。在Java应用中,单例对象能保证在一个JVM中,该对象只有一个实例存在。这样的模式有几个好处:

1、某些类创建比较频繁,对于一些大型的对象,这是一笔很大的系统开销。

2、省去了new操作符,降低了系统内存的使用频率,减轻GC压力。

3、有些类如交易所的核心交易引擎,控制着交易流程,如果该类可以创建多个的话,系统完全乱了。(比如一个军队出现了多个司令员同时指挥,肯定会乱成一团),所以只有使用单例模式,才能保证核心交易服务器独立控制整个流程。





我们来看一下懒汉模式和饿汉模式的实现代码。

/** * 饿汉模式 * @author zhou.ni  * @versionCode 1 <每次修改提交前+1> */public class HungrySingle {    private static final HungrySingle sInstance = new HungrySingle();    private HungrySingle() {    }    public static HungrySingle getInstance() {        return sInstance;    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

在饿汉模式中,初始化变量的时候最好加上 final 关键字,这样比较严谨。

/** * 懒汉模式 * @author zhou.ni  * @versionCode 1 <每次修改提交前+1> */public class LazySingle {    private static LazySingle sInstance = null;    private LazySingle() {    }    public static LazySingle getInstance() {        if (sInstance == null) {            synchronized (LazySingle.class) {                if (sInstance == null) {                    sInstance = new LazySingle();                }            }        }        return sInstance;    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

很多人奇怪,我的懒汉模式不是这样写的?为什么要这样写呢?

public static LazySingle getInstance() {        if (sInstance == null) {            sInstance = new LazySingle();        }        return sInstance;    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

一般这样写的,在大多数情况下这样写是没问题的。但是如果在多线程并发执行的时候,就会很容易出现安全隐患。

第一个线程进来判断 sInstance == null,还没有new 出实例的时候 。这个时候第二个线程也进来了,判断的sInstance 也是 null,然后也会 new 出实例的,这样就不是我们所要的单例模式了。

那我们就需要加锁了,使用 synchronized 关键字。

public static LazySingle getInstance() {    synchronized (LazySingle.class) {        if (sInstance == null) {            sInstance = new LazySingle();        }        return sInstance;    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

这样我们的安全隐患就被解决了,但是同样带来了一个问题。那就是每次都要判断锁,程序的执行效率就会比较低。所以我们就应该尽量减少判断锁的次数,以提高运行效率。加上双重判断,也就是最开始的代码。

推荐使用饿汉模式,简单,安全。


 

原创粉丝点击