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

设计模式之禅PK之创建类

创建类设计模式

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

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

  • 对比
    • 工厂方法模式:注重的是整体对象的创建
    • 建造者模式:注重是部件构建的过程,旨在通过一步步地精确构造创建出一个复杂的对象
  • 举例简单说明
    • 假如要制造一个超人
      • 工厂方法模式:直接产生出来的就是一个力大无穷、能够飞翔、内裤外穿的超人
      • 建造者模式:组装手、头、脚、躯干等部分,然后再把内裤外穿
  • 具体通过逻辑来PK
比较内容工厂方法模式生产超人建造者模式组装超人
类图
类图解释1.正宗的工厂方法模式
2.定义一个接口,然后定义两个实现,通过超人制造工厂制造超人
1.经典的建造者模式
2.哎!不对劲,通用的模式上抽象的是建造者与产品没有关系呀!!!是的,但是可以加强,在抽象建造者上使用了模板方法模式,每一个建造者都必须返回一个产品,但是产品如何制造的,由各个建造者自己负责
代码见【工厂模式超人代码】见【建造模式超人代码】

代码

  • 工厂模式超人代码

    • ISuperMan

      package com.peng.pk_gc;
      
      /**
       * @author kungfu~peng
       * @data 2017年12月8日
       * @description
       */
      public interface ISuperMan {
          // 特殊技能
          public void specialTalent();
      }
      
    • AdultSuperMan

      package com.peng.pk_gc;
      
      
      /**
       * @author kungfu~peng
       * @data 2017年12月8日
       * @description
       */
      public class AdultSuperMan implements ISuperMan {
      
          // 成年超人
          @Override
          public void specialTalent() {
              System.out.println("成年超人:超人力大无穷!");
          }
      
      }
      
    • ChildSuperMan

      package com.peng.pk_gc;
      
      /**
       * @author kungfu~peng
       * @data 2017年12月8日
       * @description
       */
      public class ChildSuperMan implements ISuperMan {
          // 儿童超人
          @Override
          public void specialTalent() {
              System.out.println("儿童超人:刀枪不入,快速运动");
          }
      
      }
      
    • SuperManFactory

      package com.peng.pk_gc;
      
      /**
       * @author kungfu~peng
       * @data 2017年12月8日
       * @description
       */
      public class SuperManFactory {
          // 定义一个生产超人的工厂
          public static ISuperMan createSuperMan(String type) {
              // 根据输入参数产生不同的超人
              if ("adultsuperman".equalsIgnoreCase(type)) {
                  // 生产成人超人
                  return new AdultSuperMan();
              } else if ("childsuperman".equalsIgnoreCase(type)) {
                  // 生产儿童超人
                  return new ChildSuperMan();
              }
              return null;
          }
      }
      
    • Client

      package com.peng.pk_gc;
      
      /**
       * @author kungfu~peng
       * @data 2017年12月8日
       * @description
       */
      public class Client {
          public static void main(String[] args) {
              // 模拟生产超人--生产一个成年超人
              ISuperMan adultSuperMan = SuperManFactory
                      .createSuperMan("adultsuperman");
              adultSuperMan.specialTalent();
              // 模拟生产超人--生产一个儿童超人
              ISuperMan childSuperMan = SuperManFactory
                      .createSuperMan("childsuperman");
              childSuperMan.specialTalent();
      
          }
      
      }
      
    • 执行结果

      成年超人:超人力大无穷!
      儿童超人:刀枪不入,快速运动
      
  • 建造模式超人代码

    • SuperMan

      package com.peng.pk_jz;
      
      /**
       * @author kungfu~peng
       * @data 2017年12月8日
       * @description
       */
      public class SuperMan {
          // 超人的躯体
          private String body;
          // 超人的特殊技能
          private String specialTalent;
          // 超人的标志
          private String specialSymbol;
      
          public String getBody() {
              return body;
          }
      
          public void setBody(String body) {
              this.body = body;
          }
      
          public String getSpecialTalent() {
              return specialTalent;
          }
      
          public void setSpecialTalent(String specialTalent) {
              this.specialTalent = specialTalent;
          }
      
          public String getSpecialSymbol() {
              return specialSymbol;
          }
      
          public void setSpecialSymbol(String specialSymbol) {
              this.specialSymbol = specialSymbol;
          }
      
      }
      
    • Builder

      package com.peng.pk_jz;
      
      /**
       * @author kungfu~peng
       * @data 2017年12月8日
       * @description
       */
      public abstract class Builder {
          // 定义一个超人的应用
          protected final SuperMan superMan = new SuperMan();
      
          // 构建超人的躯体
          public void setBody(String body) {
              this.superMan.setBody(body);
          }
      
          // 构建超人的特殊技能
          public void setSpecialTalent(String specialTalent) {
              this.superMan.setSpecialTalent(specialTalent);
          }
      
          // 构建超人的特殊标记
          public void setSymbol(String specialSymbol) {
              this.superMan.setSpecialSymbol(specialSymbol);
          }
      
          // 构建一个完整的超人
          public abstract SuperMan getSuperMan();
      }
      
    • AdultSuperMan

      package com.peng.pk_jz;
      
      /**
       * @author kungfu~peng
       * @data 2017年12月8日
       * @description
       */
      public class AdultSuperMan extends Builder {
      
          @Override
          public SuperMan getSuperMan() {
              super.superMan.setBody("强壮的躯体");
              super.superMan.setSpecialTalent("会飞行");
              super.superMan.setSpecialSymbol("胸前的S标记");
              return super.superMan;
      
          }
      
      }
      
    • ChildSuperMan

      package com.peng.pk_jz;
      
      /**
       * @author kungfu~peng
       * @data 2017年12月8日
       * @description
       */
      public class ChildSuperMan extends Builder {
      
          @Override
          public SuperMan getSuperMan() {
              super.superMan.setBody("强壮的躯体");
              super.superMan.setSpecialTalent("刀枪不入");
              super.superMan.setSpecialSymbol("胸前的小S标记");
              return super.superMan;
          }
      
      }
      
    • Director

      package com.peng.pk_jz;
      
      /**
       * @author kungfu~peng
       * @data 2017年12月8日
       * @description
       */
      public class Director {
          // 成年超人建造者的应用
          private static Builder adultSuperMan = new AdultSuperMan();
          // 儿童超人建造者的应用
          private static Builder childSuperMan = new ChildSuperMan();
      
          // 建造一个成年超人
          public static SuperMan getAdultSuperMan() {
              return adultSuperMan.getSuperMan();
          }
      
          // 建造一个儿童超人
          public static SuperMan getChildSuperMan() {
              return childSuperMan.getSuperMan();
          }
      }
      
    • Client

      package com.peng.pk_jz;
      
      /**
       * @author kungfu~peng
       * @data 2017年12月8日
       * @description
       */
      public class Client {
          public static void main(String[] args) {
              // 建造一个成人超人
              SuperMan adultSuperMan = Director.getAdultSuperMan();
              System.out.println("成人超人~~");
              System.out.println(adultSuperMan.getBody());
              System.out.println(adultSuperMan.getSpecialSymbol());
              System.out.println(adultSuperMan.getSpecialTalent());
              // 建造一个儿童超人
              SuperMan childSuperMan = Director.getChildSuperMan();
              System.out.println("儿童超人~~");
              System.out.println(childSuperMan.getBody());
              System.out.println(childSuperMan.getSpecialSymbol());
              System.out.println(childSuperMan.getSpecialTalent());
          }
      }
      
    • 执行结果

      成人超人~~
      强壮的躯体
      胸前的S标记
      会飞行
      儿童超人~~
      强壮的躯体
      胸前的小S标记
      刀枪不入
      

最佳实践

  • 工厂方法模式和建造者模式都属于对象创建类模式,都用来创建对象,但是他们之间的区别还是比较明显的
 工厂方法模式建造者模式
意图不同关注的是产品的整体,无需关注超人是怎样建造出来的
【对象创建的粗线条应用】
一个具体的产品的生产依赖各个部件的产生以及装配顺序,他关注的是一步步的组装起来
【对象创建的细线条应用】
产品的复杂度不同单一性质的产品
粗粒度
复合产品
细粒度
实际应用中选择只需要产品,不关注产品的产生过程需要详细关注一个产品的生产、安装

声明

  • 摘自秦小波《设计模式之禅》第2版;
  • 仅供学习,严禁商业用途;
  • 代码手写,没有经编译器编译,有个别错误,自行根据上下文改正;
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

乘风御浪云帆之上

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

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

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

打赏作者

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

抵扣说明:

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

余额充值