设计模式之禅之创建类PK【抽象工厂模式VS建造者模式】

设计模式之禅PK之创建类

创建类设计模式

  • 创建类模式:
    • 工厂方法模式
    • 建造者模式
    • 抽象工厂模式
    • 单例模式
    • 原型模式
  • 创建者模式的功能:
    • 提供对象的创建和管理职责
    • 工厂方法模式、抽象工厂方法模式、建造者模式他们之间有较多的相似性,容易混淆
    • 单例模式是要保持在内存中只有一个对象;原型模式是要通过复制的方式产生一个新的对象

【抽象工厂模式】VS【建造者模式】

  • 对比
    • 抽象工厂模式:实现对产品家族的创建,一个产品家族是这样一系列对象--具有不同分类维度的产品组合,采用抽象工厂模式不需要关心构建过程,只关心什么产品由什么工厂生产即可
    • 建造者模式:按照指定的蓝图建造产品,它的主要目的是通过组装零配件而产生一个新的产品

举例来比较一下

  • 现在有个需求,要生产汽车,不同工厂生产不同的汽车,宝马车生产宝马车,奔驰车生产奔驰车,车不仅具有不同的品牌,而且具有不同的用途分类,如商务用车Van,运动型车SUV,我们按照这个需求分别用两种设计模式分别来实现一下
  • 先来对比一下类图
 抽象工厂模式建造者模式
类图

具体代码实现

  • 抽象工厂模式生产汽车

    • ICar

      package com.peng.pk_cxgc;
      
      /**
       * @author kungfu~peng
       * @data 2017年12月9日
       * @description
       */
      public interface ICar {
          // 汽车生产商--名牌
          public String getBand();
          //汽车的型号
          public String getModel();
      
      }
      
    • AbsBMW

      package com.peng.pk_cxgc;
      
      /**
       * @author kungfu~peng
       * @data 2017年12月9日
       * @description
       */
      public abstract class AbsBMW implements ICar {
      
          private final static String BMW_BAND = "宝马汽车";
      
          @Override
          public String getBand() {
              return BMW_BAND;
          }
      
          @Override
          public abstract String getModel();
      
      }
      
    • AbsBenz

      package com.peng.pk_cxgc;
      
      /**
       * @author kungfu~peng
       * @data 2017年12月9日
       * @description
       */
      public abstract class AbsBenz implements ICar {
      
          private final static String BENZ_BAND = "奔驰汽车";
      
          @Override
          public String getBand() {
              return BENZ_BAND;
          }
      
          @Override
          public abstract String getModel();
      
      }
      
    • BMWSuv

      package com.peng.pk_cxgc;
      
      /**
       * @author kungfu~peng
       * @data 2017年12月9日
       * @description 宝马商务车
       */
      public class BMWSuv extends AbsBMW {
          private final static String X_SEARIES = "X系列车型SUV";
      
          @Override
          public String getModel() {
              return X_SEARIES;
          }
      
      }
      
    • BMWVan

      package com.peng.pk_cxgc;
      
      /**
       * @author kungfu~peng
       * @data 2017年12月9日
       * @description 宝马商务车
       */
      public class BMWVan extends AbsBMW {
          private final static String SEVENT_SEARIES = "7系列车型商务车";
      
          @Override
          public String getModel() {
              return SEVENT_SEARIES;
          }
      
      }
      
    • BenzSuv

      package com.peng.pk_cxgc;
      
      /**
       * @author kungfu~peng
       * @data 2017年12月9日
       * @description 宝马商务车
       */
      public class BenzSuv extends AbsBMW {
          private final static String G_SEARIES = "G系列车型SUV";
      
          @Override
          public String getModel() {
              return G_SEARIES;
          }
      
      }
      
    • BenzVan

      package com.peng.pk_cxgc;
      
      /**
       * @author kungfu~peng
       * @data 2017年12月9日
       * @description 宝马商务车
       */
      public class BenzVan extends AbsBMW {
          private final static String R_SEARIES = "R系列车型商务车";
      
          @Override
          public String getModel() {
              return R_SEARIES;
          }
      
      }
      
    • CarFactory

      package com.peng.pk_cxgc;
      
      /**
       * @author kungfu~peng
       * @data 2017年12月9日
       * @description
       */
      public interface CarFactory {
          // 生产SUV
          public ICar createSuv();
      
          // 生产Van
          public ICar createVan();
      }
      
    • BMWFactory

      package com.peng.pk_cxgc;
      
      /**
       * @author kungfu~peng
       * @data 2017年12月9日
       * @description
       */
      public class BMWFactory implements CarFactory {
      
          @Override
          public ICar createSuv() {
              return new BMWSuv();
          }
      
          @Override
          public ICar createVan() {
              return new BMWVan();
          }
      
      }
      
    • BenzFactoy

      package com.peng.pk_cxgc;
      
      /**
       * @author kungfu~peng
       * @data 2017年12月9日
       * @description
       */
      public class BenzFactory implements CarFactory {
      
          @Override
          public ICar createSuv() {
              return new BenzSuv();
          }
      
          @Override
          public ICar createVan() {
              return new BenzVan();
          }
      
      }
      
    • Client

      package com.peng.pk_cxgc;
      
      /**
       * @author kungfu~peng
       * @data 2017年12月9日
       * @description
       */
      public class Client {
          public static void main(String[] args) {
              CarFactory factory = null;
              factory = new BenzFactory();
      
              System.out.println("=========生产一辆奔驰SUV=========");
              System.out.println(factory.createSuv().getModel());
              System.out.println("=========生产一辆奔驰Van=========");
              System.out.println(factory.createVan().getModel());
      
              factory = new BMWFactory();
              System.out.println("=========生产一辆宝马SUV=========");
              System.out.println(factory.createSuv().getModel());
              System.out.println("=========生产一辆宝马Van=========");
              System.out.println(factory.createVan().getModel());
          }
      }
      
    • 执行结果

      =========生产一辆奔驰SUV=========
      G系列车型SUV
      =========生产一辆奔驰Van=========
      R系列车型商务车
      =========生产一辆宝马SUV=========
      X系列车型SUV
      =========生产一辆宝马Van=========
      7系列车型商务车
      
  • 建造者模式生产汽车

    • ICar

      package com.peng.pk_jz2;
      
      /**
       * @author kungfu~peng
       * @data 2017年12月9日
       * @description
       */
      public interface ICar {
          // 汽车车轮
          public String getWheel();
      
          // 汽车引擎
          public String getEngine();
      }
      
    • Car

      package com.peng.pk_jz2;
      
      /**
       * @author kungfu~peng
       * @data 2017年12月9日
       * @description
       */
      public class Car implements ICar {
          // 汽车车轮
          private String wheel;
          // 汽车引擎
          private String engine;
      
          // 构造函数传递参数
          public Car(String wheel, String engine) {
              super();
              this.wheel = wheel;
              this.engine = engine;
          }
      
          @Override
          public String getWheel() {
              return this.wheel;
          }
      
          @Override
          public String getEngine() {
              return this.engine;
          }
      
          @Override
          public String toString() {
              return "车的轮子是:" + this.wheel + ",车的引擎是:" + this.engine;
          }
      }
      
    • CarBuilder

      package com.peng.pk_jz2;
      
      /**
       * @author kungfu~peng
       * @data 2017年12月9日
       * @description
       */
      public abstract class CarBuilder {
          // 设计蓝图
          private BluePaint bp;
      
          public Car buildCar() {
              return new Car(buildEngine(), buildWhel());
          }
      
          protected abstract String buildWhel();
      
          protected abstract String buildEngine();
      
          // 接收一份设计蓝图
          public void receiveBluepaint(BluePaint bp) {
              this.bp = bp;
          }
      
          // 获得设计蓝图--真正的建造者才能查看蓝图
          public BluePaint getBp() {
              return bp;
          }
      
      }
      
    • BenzBuilder

      package com.peng.pk_jz2;
      
      /**
       * @author kungfu~peng
       * @data 2017年12月9日
       * @description
       */
      public class BenzBuilder extends CarBuilder {
      
          @Override
          protected String buildWhel() {
              return super.getBp().getWheel();
          }
      
          @Override
          protected String buildEngine() {
              return super.getBp().getEngine();
          }
      
      }
      
    • BMWBuilder

      package com.peng.pk_jz2;
      
      /**
      * @author kungfu~peng
      * @data 2017年12月9日
      * @description
      */
      public class BMWBuilder extends CarBuilder {
      
      @Override
      protected String buildWhel() {
          return super.getBp().getWheel();
      }
      
      @Override
      protected String buildEngine() {
          return super.getBp().getEngine();
      }
      
      }
      
    • BulePaint

      package com.peng.pk_jz2;
      
      /**
       * @author kungfu~peng
       * @data 2017年12月9日
       * @description
       */
      public class BluePaint {
          // 车轮的生产要求
          private String wheel;
          // 引擎的生产要求
          private String engine;
      
          public String getWheel() {
              return wheel;
          }
      
          public void setWheel(String wheel) {
              this.wheel = wheel;
          }
      
          public String getEngine() {
              return engine;
          }
      
          public void setEngine(String engine) {
              this.engine = engine;
          }
      
      }
      
    • Director

      package com.peng.pk_jz2;
      
      /**
       * @author kungfu~peng
       * @data 2017年12月9日
       * @description
       */
      public class Director {
          // 声明对建造者的引用
          private CarBuilder benzBuilder = new BenzBuilder();
          private CarBuilder bmwBuilder = new BMWBuilder();
      
          // 生产奔驰SUV
          public ICar createBenzSuv() {
              // 制造出汽车
              return createCar(benzBuilder, "奔驰的轮胎", "奔驰的引擎");
          }
      
          // 生产宝马商务车
          public ICar createBMWVan() {
              return createCar(bmwBuilder, "宝马车的轮胎", "宝马车的引擎");
          }
      
          // 生产出混合车型
          public ICar createComplexCar() {
              return createCar(bmwBuilder, "宝马的轮胎", "奔驰的引擎");
          }
      
          // 生产车辆
          private ICar createCar(CarBuilder cb, String wheel, String engine) {
              // 导演怀揣设计蓝图
              BluePaint bp = new BluePaint();
              bp.setEngine(engine);
              bp.setWheel(wheel);
              System.out.println("获得生产蓝图!");
              cb.receiveBluepaint(bp);
              return cb.buildCar();
          }
      }
      
    • Client

      package com.peng.pk_jz2;
      
      /**
       * @author kungfu~peng
       * @data 2017年12月9日
       * @description
       */
      public class Client {
          public static void main(String[] args) {
              // 定义出导演类
              Director director = new Director();
              // 生产一辆奔驰SUV
              System.out.println("======生产奔驰SUV=====");
              System.out.println(director.createBenzSuv());
              // 生产一辆宝马商务
              System.out.println("======生产宝马商务=====");
              System.out.println(director.createBMWVan());
      
              // 生产一辆混合车型
              System.out.println("======生产混合车型=====");
              System.out.println(director.createComplexCar());
          }
      }
      
    • 执行结果

      ======生产奔驰SUV=====
      获得生产蓝图!
      车的轮子是:奔驰的引擎,车的引擎是:奔驰的轮胎
      ======生产宝马商务=====
      获得生产蓝图!
      车的轮子是:宝马车的引擎,车的引擎是:宝马车的轮胎
      ======生产混合车型=====
      获得生产蓝图!
      车的轮子是:奔驰的引擎,车的引擎是:宝马的轮胎
      
  • 代码写完了,现在看看两者有哪些注意的地方
抽象共产模式生产汽车建造者模式生产汽车
抽象共产模式把一辆车认为是一个完整、不可拆分的对象。它注重完整性,一个产品一旦找到一个工厂生产,那就是固定的型号,不会出现一个生产宝马的工厂生产出来奔驰车的情况按照建造者设计模式设计一个生产车辆需要把车辆进行拆分,拆分成引擎和轮胎(暂且有这两个部件),然后由建造者进行建造,想要什么车,只要有设计蓝图即可,马上就可以建造出相应的车出来。它注重的是对零件的装配、组合、封装,他从一个构件装配角度看待一个对象

最佳实践

  • 我们在抽象工厂模式使用“工厂”来描述建造者,在建造者模式中使用“车间”来描述建造者
  • 关于工厂与车间
 工厂车间
观察的角度更高层次去看对象的构建,对一个领导者来说,不用关心一个工厂到底是怎样具体的生产一个产品的它是由车间组成,不同的车间完成不同的任务,一个完整的汽车需要引擎车间和轮胎车间的配合才能完成,他们的配合的基础就是汽车的设计蓝图,而蓝图掌握在车间主任(导演)的手上,建造者模式更关心的是建造的过程
尺度大小尺度大:它关注产品的整体尺度小:它关注构建过程
应用场景屏蔽对象的创建过程,只提供一个封装良好的对象可以用在装配方面

声明

  • 摘自秦小波《设计模式之禅》第2版;
  • 仅供学习,严禁商业用途;
  • 代码手写,没有经编译器编译,有个别错误,自行根据上下文改正;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乘风御浪云帆之上

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值