创建型模式:单例/工厂/Builder/原型
单例模式
构造函数设置为private、通过静态方法或枚举返回单例对象
确保单例对象有且只有一个(尤其是多线程环境)、且反序列化时不会重新构建对象
->构造函数私有化->暴露公共静态方法->确保线程安全
饿汉模式
1 2 3 4 5 6 7 8 9 10 11 12
| class Singleton { private Singleton() {} private static Singleton instance = new Singleton(); public static Singleton getInstance() { return instance; } }
|
懒汉模式
优点:单例只有在使用时才会被实例化
缺点:第一次加载时反应稍慢;每次调用getInstance都进行同步,造成不必要的同步开销
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| class Singleton { private static Singleton instance; private Singleton() {} public static synchronized Singleton getInstance() { if (instance == null) { instance = new Singleton(); } return instance; } }
|
Double Check Lock(DCL)模式
优点:解决了懒汉模式的大部分缺点、资源利用率高
缺点:第一次加载时反应稍慢
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| class Singleton { private volatile static Singleton instance = null; private Singleton() {} public static Singleton getInstance() { if (instance == null) { synchronized (Singleton.class) { if (instance == null) { instance = new Singleton(); } } } return instance; } }
|
静态内部类模式
优点:确保线程安全、保证单例、延迟了单例的实例化
1 2 3 4 5 6 7 8 9 10 11 12 13
| class Singleton { private Singleton() {} public static Singleton getInstance() { return SingletonHolder.instance; } private static class SingletonHolder{ private static final Singleton instance = new Singleton(); } }
|
以上单例方法在反序列化情况需加入以下方法
1 2 3 4 5
| private Object readResolve() throws ObjectStreamException { return instance; }
|
因为序列化可以将一个单例的实例对象写入磁盘,然后再读出来,从而有效的获取一个实例,
即使构造函数私有,反序列化依旧可以通过特殊途径获得新的实例
枚举单例
线程安全且单例,反序列化情况也不会生成新的实例
1 2 3 4
| public enum Singleton { INSTANCE; }
|
工厂模式
工厂方法模式
定义一个用于创建对象的接口,让子类决定实例化那个类
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 26 27
| * 产品抽象类 */ abstract class Product{ public abstract void method(); } * 工厂抽象类 */ abstract class Factory{ public abstract Product createProduct(); } * 工厂方法 * 通过不同的返回值生产A或B (A/B为继承自Product的类) */ class MyFactory extends Factory{ @Override public Product createProduct() { return new ProductA(); } }
|
简单工厂模式
1 2 3 4 5 6 7 8 9 10
| * 简单工厂 * 使用场景:工厂只有一个的时候 */ class SimpleFactory{ public static Product createProduct() { return new ProductA(); } }
|
抽象工厂模式
为创建一组相关或者是相互依赖的对象创建一组接口,而不需要指定他们的具体类
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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| * 抽象工厂 */ abstract class AbstractFactroy { public abstract AbstractProudctA createProductA(); public abstract AbstractProudctB createProductB(); } * 生产产品1 */ class MyFactory1 extends AbstractFactroy { @Override public AbstractProudctA createProductA() { return new ProductA1(); } @Override public AbstractProudctB createProductB() { return new ProductB1(); } } * 生产产品2 */ class MyFactory2 extends AbstractFactroy { @Override public AbstractProudctA createProductA() { return new ProductA2(); } @Override public AbstractProudctB createProductB() { return new ProductB2(); } }
|
Builder模式
将一个复杂对象的构建与他的表示分离,使得同样的构建过程可以创建不同的表示
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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
| * 抽象Builder类 */ abstract class Builder { public abstract Builder setBoard(String board); public abstract Builder setDisplay(String display); public abstract Builder setOS(String os); public abstract Computer build(); } * 具体Builder类 */ class MacBookBuilder extends Builder { private Computer mac = new MacBook(); @Override public Builder setBoard(String board) { mac.setBoard(board); return this; } @Override public Builder setDisplay(String display) { mac.setDisplay(display); return this; } @Override public Builder setOS(String os) { mac.setOs(os); return this; } @Override public Computer build() { return mac; } } public class Main { public static void main(String[] args) { Computer mac = new MacBookBuilder() .setBoard("core") .setDisplay("retina") .setOS("mac os") .build(); System.out.println(mac); } }
|
原型模式
用原型实例指定创建对象的种类,并通过拷贝这些原型,创建新对象
1 2 3 4 5 6 7 8 9 10 11 12
| class Prototype implements Cloneable { public Prototype clone() { Prototype prototype = null; try { prototype = (Prototype) super.clone(); } catch (CloneNotSupportedException e) { e.printStackTrace(); } return prototype; } }
|
具体代码参看:https://github.com/Lutils/DesignPattern