本文主要介绍工厂方法模式(Factory Method Pattern),它的定义是:“定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。”
1. 模式介绍
工厂模式(Factory Design Pattern)是一种极为常用的用于创建对象的设计模式,在绝大部份开源框架中都有最佳实践,最为人所知的大概就是 Spring 的 BeanFactory 了。
工厂模式属于创建型模式,事实上它有三种不同的实现方式:简单工厂模式、工厂方法模式、抽象工厂模式。
本文主要介绍工厂方法模式(Factory Method Pattern),它的定义是:“定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。”
由此可见,简单工厂模式与工厂方法模式的区别就是创建对象的工厂,如果有静态的创建具体产品的方法,那就是简单工厂;如果创建具体产品的方式是由公共接口而来的,那就是工厂方法模式。
2. 应用场景
工厂方法模式适用于需要灵活的、可扩展的来创建对象的场景中。抽象出一个创建同一类对象的工厂接口,创建不同的具体对象都有单独的工厂类来实现,同时会实现工厂接口。后续再新增具体对象时,不需要像简单工厂模式那样修改静态工厂方法,而是直接新增一个具体工厂类就可以了。
同时,工厂方法模式也适用于需要将产品的使用者与产品的创建进行接耦的场景。
3. 类图
工厂方法模式中有四种角色:
- 抽象产品(IProduct):描述了工厂创建的所有对象的抽象接口
- 具体产品(Concrete Product):工厂创建的具体实例,实现了抽象产品接口
- 抽象工厂(Abstract Factory):描述了工厂创建具体产品的方法,任何用来创建具体产品的工厂类必须实现该接口
- 具体工厂(Concrete Factory):创建具体产品的具体工厂类,实现了抽象工厂,描述了创建某个指定类型的具体产品的过程
4. 实现方式
还是上一篇文章中说到简单工厂模式的那个场景,如果用工厂方法模式来实现,就需要定义一个创建手机的工厂接口:
public interface PhoneFactory {
Phone getPhone();
}
两种不同类型的手机需要两个具体工厂类:
public class IPhoneFactory implements PhoneFactory {
@Override
public Phone getPhone() {
return new IPhone();
}
}
public class HuaWeiFactory implements PhoneFactory {
@Override
public Phone getPhone() {
return new HuaWei();
}
}
我们写一个 main 函数来测试改造后的代码
public static void main(String[] args) {
PhoneFactory factory = new HuaWeiFactory();
Phone huawei = factory.getPhone();
huawei.takePhotos();
}
// 输出
// 华为...也能照亮你的美
如果后续又新增了一款手机叫做小米,那么在创建了小米手机的具体产品类后,只需要再加一个用于创建小米手机的工厂类就可以了,如下所示:
public class XiaoMi implements Phone {
@Override
public void takePhotos() {
System.out.println("小米手机,就是牛");
}
}
public class XiaoMiFactory implements PhoneFactory{
@Override
public Phone getPhone() {
return new XiaoMi();
}
}
由此可见,其拓展性极好,符合“开放-封闭原则”。
5. 优缺点
看过了工厂方法模式的实现方式,我们来聊聊它的优缺点。
工厂方法模式的优点是:
- 有良好的封装性,将客户端与创建具体产品的逻辑解耦。客户端如果需要创建一个具体产品,只要知道这个具体产品的别名(类名或指定字符串)就可以了,不需要知道创建的具体流程
- 拓展性强,如果想增加一个产品,只要扩展一个工厂类就可以
工厂方法模式的缺点是:
- 代码复杂度提高,新增一个具体产品类,就需要新增一个具体工厂类。
6. 小结
本文描述了工厂方法模式的定义、应用场景、类图、实现方法以及优缺点。
6. 参考资料
最后,本文收录于个人语雀知识库: 我所理解的后端技术,欢迎来访。
文档信息
- 本文作者:Planeswalker23
- 本文链接:https://planeswalker23.github.io/2022/01/18/%E6%88%91%E6%89%80%E7%90%86%E8%A7%A3%E7%9A%84%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F%E7%B3%BB%E5%88%97-%E7%AC%AC2.2%E7%AF%87-%E4%B8%89%E7%A7%8D%E5%B7%A5%E5%8E%82%E6%A8%A1%E5%BC%8F%E5%82%BB%E5%82%BB%E5%88%86%E4%B8%8D%E6%B8%85%E6%A5%9A(2)%E5%B7%A5%E5%8E%82%E6%96%B9%E6%B3%95%E6%A8%A1%E5%BC%8F/
- 版权声明:本作品系原创,作者保留所有权利,未经作者允许,禁止转载和演绎。