五大创建型模式之三: 抽象工厂.
简介
姓名 : 抽象工厂
英文名 :Abstract Factory Pattern
价值观 : 不管你有多少产品, 给我就是了
个人介绍 :
Provide an interface for creating families of related or dependent objects without specifying their concrete classes. 为创建一组相关或相互依赖的对象提供一个接口, 而且无须指定它们的具体类. (来自《设计模式之禅》)
今天讲的是抽象工厂模式, 小伙伴可能有疑问, 抽象工厂和工厂方法之间都有工厂, 那肯定是有什么联系的, 具体是什么关系呢? 简单的说: 工厂方法是在解决一个产品多个层级方面的事情; 而抽象工厂致力于解决多个产品多个层级方面的事情. 举个例子: 汽车是由很多零件组成的, 比如引擎, 轮胎, 方向盘等等. 现在如果我们是轮胎生产方, 要生产宝马轮胎和奔驰轮胎, 要用工厂方法还是抽象工厂实现呢? 答案是: 工厂方法. 轮胎是一个产品, 宝马轮胎和奔驰轮胎是 2 个不同层级的轮胎, 所以用工厂方法解决就足够. 假如现在我们是汽车生产方, 要生产宝马汽车和奔驰汽车, 汽车又包含轮胎和方向盘等等, 要用哪个来实现? 既然是上面的是工厂方法, 那这个就用抽象工厂, 因为这涉及到多个产品 (轮胎, 方向盘等等) 和 2 个层级(宝马和奔驰). 这里还没有讲抽象工厂的概念就说了工厂方法和抽象方法的区别, 是不是有点陌生? 嗯, 先记住这个概念, 分清楚两者的区别. 在不同场景使用不同的设计模式.
上面定义中: 为创建一组相关或相互依赖的对象提供一个接口. 这样子理解这句话, 比如上面说的轮胎和方向盘, 宝马汽车用的轮胎和方向盘需要都是宝马品牌的, 也就是说在安装宝马汽车的轮胎和方向盘的时候, 得用宝马生产的轮胎和方向盘, 重要的一点是: 轮胎和方向盘是互相依赖的, 不能在宝马汽车上安装奔驰轮胎和宝马方向盘, 因为有这个依赖关系, 所以我们需要提供一个额外的接口, 来保证宝马汽车使用的轮胎和方向盘都是宝马生产的. 这就是抽象工厂干的事情.
你要的故事
上面用汽车安装轮胎和方向盘的例子, 那这里为了让大家能深入理解, 就不用其他例子了. 在一个设计模式讲解的过程中, 我觉得用一个案例来讲解可以减少读者的阅读理解成本, 为了写设计模式这一系列文章, 看了不少设计模式方面的书籍, 有些书籍在讲解一个设计模式的时候, 用了不止一个例子, 读完之后印象不是很深刻. 这个系列写完之后, 想要的效果是: 不需要记住设计模式的定义, 把这些故事以及故事对应是讲哪个设计模式都记住了, 就真正掌握了这些内容了.
- public class AbstractFactoryTest {
- public static void main(String[] args) {
- // 宝马员工安装轮胎和方向盘
- AbstractCarFactory bmwCarFacatory = new BMWCarFactory();
- bmwCarFacatory.installWheel();
- bmwCarFacatory.installSteeringWheel();
- // 奔驰员工安装轮胎和方向盘
- AbstractCarFactory mercedesCarFacatory = new MercedesCarFacatory();
- mercedesCarFacatory.installWheel();
- mercedesCarFacatory.installSteeringWheel();
- }
- }
- /**
- * 汽车抽象工厂
- */
- interface AbstractCarFactory {
- void installWheel();
- void installSteeringWheel();
- }
- /**
- * 宝马工厂
- */
- class BMWCarFactory implements AbstractCarFactory {
- @Override
- public void installWheel() {
- WheelFacatory wheelFacatory = new BMWWheelFacatory();
- String wheel = wheelFacatory.createWheel();
- System.out.println("安装轮胎:" + wheel);
- }
- @Override
- public void installSteeringWheel() {
- SteeringWheelFacatory steeringWheelFacatory = new BMWSteeringWheelFacatory();
- String steeringWheel = steeringWheelFacatory.createSteeringWheel();
- System.out.println("安装方向盘:" + steeringWheel);
- }
- }
- /**
- * 奔驰工厂
- */
- class MercedesCarFacatory implements AbstractCarFactory {
- @Override
- public void installWheel() {
- WheelFacatory wheelFacatory = new MercedesWheelFacatory();
- String wheel = wheelFacatory.createWheel();
- System.out.println("安装轮胎:" + wheel);
- }
- @Override
- public void installSteeringWheel() {
- SteeringWheelFacatory steeringWheelFacatory = new MercedesSteeringWheelFacatory();
- String steeringWheel = steeringWheelFacatory.createSteeringWheel();
- System.out.println("安装方向盘:" + steeringWheel);
- }
- }
- /**
- * 轮胎工厂
- */
- interface WheelFacatory {
- String createWheel();
- }
- /**
- * 宝马轮胎工厂
- */
- class BMWWheelFacatory implements WheelFacatory {
- @Override
- public String createWheel() {
- System.out.println("宝马轮胎工厂生产轮胎");
- return "宝马轮胎";
- }
- }
- /**
- * 奔驰轮胎工厂
- */
- class MercedesWheelFacatory implements WheelFacatory {
- @Override
- public String createWheel() {
- System.out.println("奔驰轮胎工厂生产轮胎");
- return "奔驰轮胎";
- }
- }
- /**
- * 方向盘工厂
- */
- interface SteeringWheelFacatory {
- String createSteeringWheel();
- }
- /**
- * 宝马方向盘工厂
- */
- class BMWSteeringWheelFacatory implements SteeringWheelFacatory {
- @Override
- public String createSteeringWheel() {
- System.out.println("宝马方向盘工厂生产方向盘");
- return "宝马方向盘";
- }
- }
- /**
- * 奔驰方向盘工厂
- */
- class MercedesSteeringWheelFacatory implements SteeringWheelFacatory {
- @Override
- public String createSteeringWheel() {
- System.out.println("奔驰方向盘工厂生产方向盘");
- return "奔驰方向盘";
- }
- }
代码:
还是和以往一样, 思维开拓一下, 这里列举的是给汽车安装轮胎和方向盘, 汽车不止这些, 如果要加个安装引擎呢? 要怎么实现? 这里我就不写出来了, 让小伙伴尝试一下, 写出来了就理解抽象模式这个设计模式啦.
总结
简单工厂, 工厂方法, 抽象工厂这几个工厂相关的设计模式的基本内容都讲完了, 这几个模式都是为了解耦, 为了可扩展. 这里要着重说一下, 三者之间没有好坏之分, 只有在具体的场景才能发挥它们各自的优势. 在单产品多层级, 层级数量不多的情况下, 可以使用简单工厂, 层级多且需要支持扩展, 可以使用工厂方法; 在多产品多层级, 可以使用抽象工厂.
参考资料:《大话设计模式》,《Java 设计模式》,《设计模式之禅》,《研磨设计模式》,《Head First 设计模式》
来源: https://juejin.im/post/5c4476b3f265da61736a8fbf