设计模式——抽象工厂模式

228 阅读5分钟

WX 搜索:程序员个人修养

定义

抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类

首先,我们来理解下产品族的概念。

我们还是以咖啡厅为例,我们知道,社会上不只有星巴克咖啡一个品牌,还有我们国产的瑞幸咖啡、上岛咖啡、咖啡之翼等。而这每种品牌下,都会提供拿铁、摩卡、卡布奇诺等不同口味的咖啡。

产品族就可以看做是同一品牌下的同不同口味的咖啡,比如:星巴克品牌的拿铁咖啡、摩卡咖啡和卡布奇诺咖啡称为一个产品族。同样,瑞幸咖啡和咖啡之翼又代表了另外的产品族。

抽象工厂的适用于这种需要生成产品族的情景。抽象产品类内部提供了多个其他抽象产品,抽象工厂类定义了产品的创建接口,通过具体的工厂子类,就可以生产出相应的产品族对象。

类图

抽象工厂类图.png

抽象工厂模式主要包含四个角色:

  • 抽象工厂:声明创建抽象产品对象的一个操作接口;
  • 具体工厂:实现创建具体产品对象的操作;
  • 抽象产品:为一类产品对象声明一个接口;
  • 具体产品:定义一个将被相应的具体工厂创建的产品对象;

代码实现

 package com.study.design.Factory.abstractfactory;
 ​
 /**
  * 抽象产品
  * 拿铁咖啡
  */
 public interface Latte {
 ​
     void coffeName();
 }
 package com.study.design.Factory.abstractfactory;
 ​
 /**
  * 抽象产品
  * 拿铁咖啡
  */
 public interface Mocha {
 ​
     void coffeName();
 }
 package com.study.design.Factory.abstractfactory;
 ​
 /**
  * 产品族中的一个具体产品:拿铁咖啡
  * 产品组族:瑞幸咖啡
  */
 public class RuiXingLatte implements Latte{
     @Override
     public void coffeName() {
         System.out.println("I got a RuiXingLatte");
     }
 }
 package com.study.design.Factory.abstractfactory;
 ​
 /**
  * 产品族中的一个具体产品:摩卡咖啡
  * 产品组族:瑞幸咖啡
  */
 public class RuiXingMocha implements Mocha{
     @Override
     public void coffeName() {
         System.out.println("I got a RuiXingMocha");
     }
 }
 package com.study.design.Factory.abstractfactory;
 ​
 /**
  * 产品族中的一个具体产品:摩卡咖啡
  * 产品组族:星巴克
  */
 public class StarbuckeMocha implements Mocha{
     @Override
     public void coffeName() {
         System.out.println("I got a StarbuckeMocha");
     }
 }
 package com.study.design.Factory.abstractfactory;
 ​
 /**
  * 产品族中的一个具体产品:拿铁咖啡
  * 产品组族:星巴克
  */
 public class StarbucksLatte implements Latte{
 ​
     @Override
     public void coffeName() {
         System.out.println("I got a StarbucksLatte");
     }
 }
 package com.study.design.Factory.abstractfactory;
 ​
 import sun.misc.GC;
 ​
 /**
  * 产品族中的一个具体产品:拿铁咖啡
  * 产品组族:咖啡之翼
  */
 public class WingCoffeLatte implements Latte {
     @Override
     public void coffeName() {
         System.out.println("I got a WingCoffeLatte");
     }
 }
 package com.study.design.Factory.abstractfactory;
 ​
 /**
  * 产品族中的一个具体产品:摩卡咖啡
  * 产品组族:咖啡之翼
  */
 public class WingCoffeMocha implements Mocha{
     @Override
     public void coffeName() {
         System.out.println("I got a WingCoffeMocha");
     }
 }
 package com.study.design.Factory.abstractfactory;
 ​
 /**
  * 抽象工厂
  * 咖啡厅接口
  */
 public interface CoffeShop {
     // 制作拿铁咖啡
     Latte makeLate();
     // 制作摩卡咖啡
     Mocha makeMocha();
 ​
 }
 package com.study.design.Factory.abstractfactory;
 ​
 /**
  * 具体工厂
  * 瑞幸咖啡厅
  */
 public class RuiXingCoffeShop implements CoffeShop{
     @Override
     public Latte makeLate() {
         return new RuiXingLatte();
     }
 ​
     @Override
     public Mocha makeMocha() {
         return new RuiXingMocha();
     }
 }
 package com.study.design.Factory.abstractfactory;
 ​
 /**
  * 具体工厂
  * 星巴克咖啡厅
  */
 public class StarbucksShop implements CoffeShop{
     @Override
     public Latte makeLate() {
         return new StarbucksLatte();
     }
 ​
     @Override
     public Mocha makeMocha() {
         return new StarbuckeMocha();
     }
 }
 package com.study.design.Factory.abstractfactory;
 ​
 /**
  * 具体工厂
  * 咖啡之翼咖啡厅
  */
 public class WingCoffeCoffeShop implements CoffeShop{
     @Override
     public Latte makeLate() {
         return new WingCoffeLatte();
     }
 ​
     @Override
     public Mocha makeMocha() {
         return new WingCoffeMocha();
     }
 }
 package com.study.design.Factory.abstractfactory;
 ​
 public class AbstractFactoryTest {
     public static void main(String[] args) {
         // 产品组族:瑞幸咖啡厅
         CoffeShop coffeShop = new RuiXingCoffeShop();
         Latte latte = coffeShop.makeLate();
         latte.coffeName();
         Mocha mocha = coffeShop.makeMocha();
         mocha.coffeName();
         // 产品组族:星巴克咖啡厅
         coffeShop = new StarbucksShop();
         latte = coffeShop.makeLate();
         latte.coffeName();
         mocha = coffeShop.makeMocha();
         mocha.coffeName();
         // 产品组族:咖啡之翼咖啡厅
         coffeShop = new WingCoffeCoffeShop();
         latte = coffeShop.makeLate();
         latte.coffeName();
         mocha = coffeShop.makeMocha();
         mocha.coffeName();
     }
 }

三种工厂模式对比

简单工厂模式

简单工厂模式(又叫作静态工厂方法模式)有一个具体的工厂类,可以生成多个不同的产品,属于创建型设计模式。简单工厂模式不在 GoF 23种设计模式之列。

对于产品种类较少的情况,考虑使用简单工厂模式可以很方便的创建所需对象。使用简单工厂模式的客户端只需要传入相应的参数,不需要关心创建对象的逻辑。

简单工厂模式的结构简单,调用方便。对于外界给定的信息,可以很方便地创建出相应的产品。工厂和产品的职责区分明确。但是单一工厂类负责所有产品的创建,当产品数量增多时,工厂类代码会非常臃肿,违背高聚合原则。

工厂方法模式

在工厂方法模式中,不再由单一工厂类生产产品,而是由工厂类的子类实现具体产品的创建。因此,当增加一个产品时,只需要增加一个相应的工厂类子类即可,解决了简单工厂中代码臃肿的问题,也符合开闭原则。

灵活性增强,对于新产品的创建,只需要写一个相应的工厂类。典型的解耦框架,高层模块只需要知道产品的抽象类,无需关心其他实现类。

但是类的个数容易过多,增加复杂度,也增加了系统的抽象性和理解难度。对于抽象产品只能生产一种产品的问题,可以通过抽象工厂模式解决。

抽象工厂模式

当需要产品族时,抽象工厂可以保证客户端始终只使用同一个产品的产品族。增强了程序的可扩展性,对于新产品族的增加,只需要实现一个新的具体工厂即可,符合开闭原则。但是在产品族中扩展新的产品困难,需要修改抽象工厂的接口。增加了系统的抽象性和理解难度。

WX 搜索:程序员个人修养