创建型模式(五种):单例模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式
结构型模式(七种):适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式
行为型模式(十一种):策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

Singleton 单例模式

一个类在 Java 虚拟机中只有一个对象,并提供一个全局访问点。

生活中例子:太阳、月亮。

项目里面怎么用:数据库连接对象,属性配置文件的读取对象。

懒汉式-线程不安全

以下实现中,私有静态变量 uniqueInstance 被延迟实例化,这样做的好处是,如果没有用到该类,那么就不会实例化 uniqueInstance,从而节约资源。

这个实现在多线程环境下是不安全的,如果多个线程能够同时进入 if (uniqueInstance == null) ,并且此时 uniqueInstance 为 null,那么会有多个线程执行 uniqueInstance = new Singleton(); 语句,这将导致实例化多次 uniqueInstance。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Singleton {

private static Singleton uniqueInstance;

private Singleton() {
}

public static Singleton getUniqueInstance() {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
}

饿汉式-线程安全

线程不安全问题主要是由于 uniqueInstance 被实例化多次,采取直接实例化 uniqueInstance 的方式就不会产生线程不安全问题。

但是直接实例化的方式也丢失了延迟实例化带来的节约资源的好处。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//饿汉式单例类.在类初始化时,已经自行实例化   
public class EagerSingleton {
private static EagerSingleton instance = new EagerSingleton();
/**
* 构造方法私有化
*/
private EagerSingleton(){}
/**
* 静态工厂方法
*/
public static EagerSingleton getInstance(){
return instance;
}
}

Simple Factory 简单工厂模式

用一个方法来代替new关键字。

在创建一个对象时不向客户暴露内部细节,并提供一个创建对象的通用接口。

项目里面怎么用:对于经常生成的对象,或者父子类替换的对象。spring的核心就是工厂模式。

1
2
3
4
5
6
7
8
9
public class UserFactory {  
public static User createUser(int i){
//如果输入的是1,就创建它的子类,否则就创建父类
if(i==1){
return new Alices();
}
return new User();
}
}

Proxy 代理模式

为其他对象提供一个代理,以控制对当前对象的访问。

项目里面怎么用:权限,或者大对象的访问权限。

框架里面使用:Spring里面的AOP实现。

实现:设置一个顶级接口,被代理类和代理类都实现该接口。代理类里实例化被代理类,并且控制外界对被代理类对象的访问。

Decorator 装饰模式

为对象动态添加功能。

应用场景:IO 流包装、 数据源包装、 简历包装

Adapter 适配器模式

把一个类接口转换成另一个用户需要的接口。

生活中的例子:转换插头

框架里面使用:Spring AOP 模块对 BeforeAdvice、 AfterAdvice、 ThrowsAdvice 三种通知类型的支持实际上是借助适配器模式来实现的

  • java.util.Collections#list()

Strategy 策略模式

定义一系列算法并可以互相替换。

生活中的例子:图片的格式,压缩文件的格式。

项目里面怎么用:购物车里面的付款方式。

实现:设置一个顶级接口,各子类分别在实现接口方法时重写该方法。

Observer 观察者模式

定义对象之间的一对多依赖,当一个对象状态改变时,它的所有依赖都会收到通知并且自动更新状态。

应用场景:监听器、日志收集、短信通知、邮件通知

  • javax.servlet.http.HttpSessionBindingListener