23种设计模式
总体来说设计模式分为三大类:
创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
一、介绍
- 单件模式——确保一个类只有一个实例,并提供全局访问点。
- Java中实现单件模式需要一个静态变量、一个静态方法、私有构造器。
二、方式一:懒加载
下面是一个“巧克力熔炉”的单例设计,如下,只需私有构造器、静态变量、静态 getInstance方法,就可以创建单例对象了。
/**
* 巧克力熔炉
*/
public class ChocolateBoiler {
private boolean empty;
private boolean boiled;
private static ChocolateBoiler uniqueInstance;
private ChocolateBoiler() {
empty = true;
boiled = false;
}
// 以下代码在多线程环境下,可能会创建出多例对象
public static ChocolateBoiler getInstance() {
if (uniqueInstance == null) {
System.out.println("Creating unique instance of Chocolate Boiler");
uniqueInstance = new ChocolateBoiler();
}
System.out.println("Returning instance of Chocolate Boiler");
return uniqueInstance;
}
public void fill() {
if (isEmpty()) {
empty = false;
boiled = false;
// fill the boiler with a milk/chocolate mixture
}
}
public void drain() {
if (!isEmpty() && isBoiled()) {
// drain the boiled milk and chocolate
empty = true;
}
}
public void boil() {
if (!isEmpty() && !isBoiled()) {
// bring the contents to a boil
boiled = true;
}
}
public boolean isEmpty() {
return empty;
}
public boolean isBoiled() {
return boiled;
}
}
问题:
三、方式二:同步 getInstance()
使用 synchronized 方式,保证进入到代码区的线程只有一个,其他线程必须等待上一个线程执行完成。
但是,使用 synchronized 又会带来另一个问题,就是降低了效率。想象一下,我们已经创建了唯一实例了,下次再次调用 getInstance() 方法时,又会进入到 synchronized同步代码块当中。其实这样已经没必要再同步了,直接return即可。
四、方式三:急切实例化
五、方式四:双重加锁
/**
* 双重加锁:保证只有第一次创建实例时才会同步
*/
public class Singleton02 {
private volatile static Singleton02 uniqueInstance;
private Singleton02(){
}
public static Singleton02 getInstance(){
if (uniqueInstance == null){
synchronized (Singleton02.class){
if (uniqueInstance == null){
uniqueInstance = new Singleton02();
}
}
}
return uniqueInstance;
}
}
六、单例模式的细节问题
单件模式不一定适合作为父类。