创建型设计模式是处理对象创建的设计模式,主要特点是“将对象的创建与业务代码分离”。一共有五种:工厂方法模式、单例模式、原型模式、抽象工厂模式及建造者模式。
1 单例模式
需求:
- 在整个系统中只需要一个实例。
- 管理共享资源,例如数据库连接、配置文件读取等,可以减少资源消耗,提高性能。
1.1 单例模式介绍
确保某个类只有一个实例,自行实例化并且向整个系统提供这个实例。

图 单例模式UML
| 饿汉模式 | 在程序启动时就进行对象的实例化,单例对象会在类被加载时创建。实现简单、线程安全。但是无法进行懒加载,会带来一定的系统开销。 | 
| 懒汉模式 | 类加载时不会创建单例对象,而是等到真正需要的时候才创建。懒汉模式第一次调用时才初始化,避免了内存浪费,但是需要注意线程安全问题。 | 
| 枚举 | 实现单例的最佳方法,自动支持序列化机制、防止多次实例化并且线程安全。 | 
图 实现单例模式的方式
public class HungryModel {
    private HungryModel() {}
    private final static HungryModel instance = new HungryModel();
    public static HungryModel getInstance() {
        return instance;
    }
}public class DoubleCheckLocking {
    private DoubleCheckLocking() {}
    private static DoubleCheckLocking instance = null;
    public static DoubleCheckLocking getInstance() {
        if (instance == null) {
            synchronized (DoubleCheckLocking.class) {
                if (instance == null) instance = new DoubleCheckLocking();
            }
        }
        return instance;
    }
}public class IoDHSingleton {
    private IoDHSingleton() {}
    private static class Holder {
        static final IoDHSingleton instance = new IoDHSingleton();
    }
    public static IoDHSingleton getInstance() {
        return Holder.instance;
    }
}1.1.1 优缺点
优点:确保一个类在系统中只有一个实例,节约系统资源,提高性能。
缺点:不符合单一职责原则。
2 原型模式
需求:
- 需要频繁创建属性近似的对象。
- 需要保持对象在某个时刻的状态。
2.1 原型模式介绍
通过一个已存在的对象克隆出多个一摸一样的对象。

图 原型模式UML
public class Address implements Cloneable{
    public Address() {}
    @Override
    public Address clone() throws CloneNotSupportedException {
        return (Address)super.clone();
    }
    @Override
    public String toString() {
        return "Address(" + Integer.toHexString(hashCode()) + ")";
    }
}
public class User implements Cloneable{
    private List<Address> addressList;
    public void setAddressList(List<Address> addressList) {
        this.addressList = addressList;
    }
    @Override
    public User clone() throws CloneNotSupportedException {
        User clone = (User)super.clone();
        if (addressList != null) {
            List<Address> newList = new ArrayList<>();
            for (Address address : addressList) {
                newList.add(address.clone());
            }
            clone.setAddressList(newList);
        }
        return clone;
    }
    public static void main(String[] args) throws CloneNotSupportedException {
        User user = new User();
        List<Address> addresses = new ArrayList<>();
        addresses.add(new Address());
        addresses.add(new Address());
        user.setAddressList(addresses);
        User clone = user.clone();
        System.out.println(user);
        System.out.println(clone);
    }
    @Override
    public String toString() {
        return "User(" + Integer.toHexString(hashCode()) +"){" +
                "addressList=" + addressList +
                '}';
    }
}2.1.1 优缺点
优点:1)减少了代码量;2)可读性、可维护性好,耦合度减小。
缺点:2)不符合单一职责原则;2)不符合开闭原则。当对象添加新的属性时可能需要修改代码。
3 工厂方法模式
需求:
- 将对象创建与业务代码剥离。
- 让用户在不需要知道具体的类型情况下,创建符合的对象。
- 隐藏创建这个实例的创建细节。
3.1 工厂方法模式介绍
将对象的创建与自身的业务逻辑分离。定义一个有创建对象接口的工厂,把创建对应产品的细节封装在不同的工厂实现类中。每增加新的产品,只需增加该产品以及对应的工厂实现类。

图 工厂方法模式UML
public class Car {
    private String engine;
    protected Car(String engine) {
        this.engine = engine;
    }
}
public class BMWCar extends Car{
    public BMWCar(String engine) {
        super(engine);
    }
}
public class TeslaCar extends Car{
    public TeslaCar(String engine) {
        super(engine);
    }
}
public interface CarFactory {
    Car buildCar();
}
public class BMWCarFactory implements CarFactory{
    @Override
    public Car buildCar() {
        return new BMWCar("汽油发动机");
    }
}
public class TeslaCarFactory implements CarFactory{
    @Override
    public Car buildCar() {
        return new TeslaCar("电动发动机");
    }
}public class CarShop {
    public static void main(String[] args) {
        CarFactory carFactory = new BMWCarFactory();
        carFactory.buildCar();
        carFactory = new TeslaCarFactory();
        carFactory.buildCar();
    }
}3.1.1 优缺点
优点:1)符合单一职责原则,可读性好。2)符合开闭原则,扩展性好。3)符合依赖倒置原则,耦合度降低。
缺点:类的数量增加,增加了系统的复杂性,可能会影响性能。



















