所谓抽象工厂模式就是提供一个接口,用于创建相关或者依赖对象的家族,而不需要明确指定具体类。
他允许客户端使用抽象的接口来创建一组相关的产品,而不需要关系实际产出的具体产品是什么。这样一来,客户就可以从具体的产品中被解耦。
它的优点是隔离了具体类的生成,使得客户端不需要知道什么被创建了,而缺点就在于新增新的行为会比较麻烦,因为当添加一个新的产品对象时,需要更加需要更改接口及其下所有子类。其UML结构图如下:
优点:
- 分离接口和实现。客户端面向产品的接口编程,从具体的产品实现中解耦。
- 可以很方便的生产或切换产品系列。
缺点:
- 不太容易扩展新产品。假如我们要给产品系列添加新的产品耳麦,那么就需要修改抽象工厂,这样就会导致修改所有的工厂实现类。
代码实例
假设汽车发动机和轮子是我们需要的产品,生产发动机和轮子的奔驰和宝马是我们的工厂。
1、创建发动机接口和具体的发动机实现类
Engine.java
/** * 发动机接口 */public interface Engine {/** * 启动发动机 */public void start();}
BenEngine.java
/** * 奔驰发动机 */public class BenEngine implements Engine {@Overridepublic void start() {System.out.println("启动奔驰发动机!");}}
BmEngine.java
/** * 宝马发动机 */public class BmEngine implements Engine {@Overridepublic void start() {System.out.println("启动宝马发动机");}}
2、创建轮子接口和具体的轮子实现类
Wheel.java
/** * 轮子接口 */public interface Wheel {/** * 转动轮子 */public void turn();}
BenWheel.java
/** * 奔驰轮子 */public class BenWheel implements Wheel {@Overridepublic void turn() {System.out.println("汽车用奔驰轮子");}}
BmWheel.java
/** * 宝马轮子 */public class BmWheel implements Wheel {@Overridepublic void turn() {System.out.println("汽车用宝马轮子");}}
3、创建获取发动机对象和轮子对象的抽象工厂
AbstractFactory.java
/** * 抽象工厂的接口,声明创建抽象产品对象的操作 */public interface AbstractFactory {/** * 创建发动机对象 * @return */public Engine createEngine();/** * 创建轮子对象 * @return */public Wheel createWheel();}
4、创建实现了抽象工厂的子工厂:奔驰工厂和宝马工厂
/** * 奔驰工厂,生产奔驰发动机和轮子 */public class BenFactory implements AbstractFactory {@Overridepublic Engine createEngine() {return new BenEngine();}@Overridepublic Wheel createWheel() {return new BenWheel();}}
/** * 宝马工厂,生产宝马发动机和轮子 */public class BmFactory implements AbstractFactory {@Overridepublic Engine createEngine() {return new BmEngine();}@Overridepublic Wheel createWheel() {return new BmWheel();}}
5、汽车组装的时候,就可以这样用:
public class Car {public static void main(String[] args) {// 使用奔驰工厂AbstractFactory af = new BenFactory();Mouse m = af.createMouse();Keyboard kb = af.createKeyboard();m.start(); // 使用奔驰发动机启动kb.turn(); // 使用奔驰轮子// 更换为宝马工厂af = new BmFactory();m = af.createMouse();kb = af.createKeyboard();m.start(); // 使用宝马发动机启动kb.turn(); // 使用宝马轮子}}
应用场景
- 我们通常看到的网站或软件,支持更换界面主题或者一键换肤。
- 当系统要支持多数据源,DAO层支持多种类型的数据库,动态切换时。
以上,是个人总结的抽象工厂模式知识点,仅供参考,有不同看法,可以评论区交流。
我是一名码龄10年的程序员,在这里会分享实在干货,让你少走弯路,成就精彩人生。