【再探】设计模式— 工厂方法、单例及原型模式

创建型设计模式是处理对象创建的设计模式,主要特点是"将对象的创建与业务代码分离"。一共有五种:工厂方法模式、单例模式、原型模式、抽象工厂模式及建造者模式。

1 单例模式

需求:

  1. 在整个系统中只需要一个实例。
  2. 管理共享资源,例如数据库连接、配置文件读取等,可以减少资源消耗,提高性能。

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 原型模式

需求:

  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 工厂方法模式

需求:

  1. 将对象创建与业务代码剥离。
  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)符合依赖倒置原则,耦合度降低。

**缺点:**类的数量增加,增加了系统的复杂性,可能会影响性能。

相关推荐
geovindu2 小时前
go: Mediator Pattern
设计模式·golang·中介者模式
kyriewen7 小时前
代码写成一锅粥?3个设计模式让你的项目“起死回生”
前端·javascript·设计模式
S1998_1997111609•X7 小时前
论mysql国盾shell-sfa犯罪行为集团下的分项工程及反向注入原理尐深度纳米算法下的鐌檵鄐鉎行为
网络·数据库·网络协议·百度·开闭原则
Pkmer16 小时前
古法编程: 适配器模式
java·设计模式
rKWP8gKv717 小时前
单例模式在Java中的7种实现:从懒汉式到静态内部类
java·开发语言·单例模式
清水白石00820 小时前
生成器不是性能银弹:什么时候该用 `yield` 省内存,什么时候它会拖慢 Python 数据处理吞吐?
开发语言·python·原型模式
梦想画家20 小时前
唤醒沉睡的数据:ERP销售模块接入Apache AGE实战指南
知识图谱·原型模式
灰子学技术1 天前
Envoy 使用的设计模式技术文档
设计模式
Alex艾力的IT数字空间2 天前
再思“把事情做对”与“把事情做好”的辩证关系与先后顺序
信息可视化·需求分析·学习方法·抽象工厂模式·远程工作·原型模式·中介者模式
bzmK1DTbd2 天前
SOLID原则在Java中的实践:单一职责与开闭原则
java·开发语言·开闭原则