创建型模式

建造者

将复杂对象的构建与表示相分离,同样的构建过程可以创建不同的表示

classDiagram
    class Builder {
        +buildPart()
    }
    class ConcreteBuilder {
        +buildPart()
        +getResult()
    }
    Builder <|-- ConcreteBuilder
    ConcreteBuilder --> Product
    class Director {
        +construct()
    }
    Director o--> Builder
interface Builder{
    Builder process1();
    Builder process2();
    Builder process3();
    Product build();
}
class ConcreteBuilder implements Builder{
    // 方法实现...
}
class ProductDirector{
    public Product constructProduct(Builder builder){
        builder.process1();
        builder.process2();
        builder.process3();
        return builder.build();
    }
}
// 使用
ProductDirector director = new ProductDirector();
Product product = director.constructProduct(new ConcreteBuilder());

工厂模式

简单工厂

客户无需知道具体产品的名称,只需要知道产品类所对应的参数即可

class Factory{
    public Product get(int condition){
        switch(condition){
            case 1:
                return new Product1();
            case 2:
                return new Product2();
        }
        return null;
    }
}

但是工厂的职责过重,而且当类型过多时不利于系统的扩展维护

工厂方法

定义一个接口,让子类创建该接口的实例,也就是将实例化延迟到工厂的子类

classDiagram
    ConcreteProduct --|> Product
    class ConcreteCreator {
        +factoryMethod() ConcreteProduct
    }
    class Creator {
        +factoryMethod() Product
        +operation()
    }
    ConcreteCreator --|> Creator
    ConcreteCreator ..> ConcreteProduct

模板方式和工厂模式的核心思想非常类似, 都是把一些操作留给子类去实现。模板方法经常使用工厂方法作为其算法的一部分

abstract class AbstractCreator{
    abstract Product get();

    public void doSomething(){
        // do something
        Product product = get();
        // do something
    }
}
class Creator1 extends AbstractCreator{
    Product get(){...}
}
class Creator2 extends AbstractCreator{
    Product get(){...}
}
// 使用
Factory factory = new Creator2();
Product product = factory.doSomething();

抽象工厂

提供一个创建一系列相关或相互依赖对象的接口,而无需指定具体类

classDiagram
    class AbstractFactory {
        +createProductA()
        +createProductB()
    }
    class ConcreteFactory1 {
        +createProductA()
        +createProductB()
    }
    class ConcreteFactory2 {
        +createProductA()
        +createProductB()
    }
    ConcreteFactory1 --|> AbstractFactory
    ConcreteFactory2 --|> AbstractFactory
    
    ProductA1 --|> AbstractProductA
    ProductA2 --|> AbstractProductA
    
    ProductB1 --|> AbstractProductB
    ProductB2 --|> AbstractProductB

    client ..> AbstractFactory
    client ..> AbstractProductA
    client ..> AbstractProductB
abstract class Factory{
    abstract Product get(int condition);
}
class ProductAFactory extends Factory{
    ProductA get(int condition){...}
}
class ProductBFactory extends Factory{
    ProductB get(int condition){...}
}
// 使用
Factory factory = new ProductAFactory();
Product product = factory.get(condition);

在实践中,每个工厂一般都会是单例。工厂内部可使用原型模式来实现

原型

通过一个原型对象创建新的对象

classDiagram
    class Prototype {
        +clone()
    }
    class ConcretePrototype1 {
        +clone()
    }
    class ConcretePrototype2 {
        +clone()
    }
    Prototype <|-- ConcretePrototype1
    Prototype <|-- ConcretePrototype2
    Client --> Prototype
class Product {
    Part1 part1;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Product product = (Product) super.clone();
        product.part1 = (Part1)part1.clone();
        return product;
    }
}

单例

一个类仅有一个实例,并只拥有一个全局访问点

问题:谁来销毁单例对象?什么时候销毁?

饿汉式

public class Singleton {
    private static final Singleton SINGLETON = new Singleton();
    private Singleton() { }
    
    public static Singleton getInstance(){
        return SINGLETON;
    }
}

懒汉式

public class Singleton {
    private static Singleton SINGLETON ;
    private Singleton() { }

    // 线程不安全
    public static Singleton getInstance(){
        if (SINGLETON == null){
            SINGLETON = new Singleton();
        }
        return SINGLETON;
    }
}

静态内部类方式

public class Singleton {
    
    private Singleton() { }

    private static class SingletonClass{
        public static final Singleton SINGLETON = new Singleton();
    }
    
    public static Singleton getInstance(){
        return SingletonClass.SINGLETON;
    }
}

枚举单例

public class Singleton {

    private Singleton() { }

    private enum  SingletonEnum{
        INSTANCE;
        private Singleton singleton;

        SingletonEnum() {
            singleton = new Singleton();
        }

        public Singleton getSingleton() {
            return singleton;
        }
    }

    public static Singleton getInstance(){
        return SingletonEnum.INSTANCE.getSingleton();
    }
}

双重检测加锁

public class Singleton {

    private static volatile Singleton SINGLETON; // 如果没有volatile JVM的指令重排序很有可能导致实例化多个对象

    private Singleton() { }

    public static Singleton getInstance(){
        if (SINGLETON == null){
            synchronized (Singleton.class){
                if (SINGLETON == null){
                    SINGLETON = new Singleton();
                }
            }
        }
        return SINGLETON;
    }
}
// SINGLETON = new Singleton() 可以分解为以下三个步骤
1 memory=allocate();// 分配内存 相当于c的malloc
2 ctorInstanc(memory) //初始化对象
3 s=memory //设置s指向刚分配的地址

// 上述三个步骤可能会被重排序为 1-3-2,也就是:
1 memory=allocate();// 分配内存 相当于c的malloc
3 s=memory //设置s指向刚分配的地址
2 ctorInstanc(memory) //初始化对象