设计模式——创建型_建造者模式

  • 传统Builder模式
  • 简单版Builder模式
  • 总结

1. 传统建造者模式

1.1 需求

  • 造电脑,有不同的品牌(苹果,联想),其中cpu和ram是必须的电脑组件,其他组件(keyboard, display, usbCount)是可选组件

1.2 类图

builder共四个角色

  • Product: 最终要生成的对象,例如 Computer 实例
  • Builder: 构建者的抽象基类(有时会使用接口代替)。其定义了构建Product的抽象步骤,其实体类需要实现这些步骤。其会包含一个用来返回最终产品的方法Product getProduct()
  • ConcreteBuilder: Builder的实现类
  • Director: 决定如何构建最终产品的算法. 其会包含一个负责组装的方法void Construct(Builder builder), 在这个方法中通过调用builder的方法,就可以设置builder,等设置完成后,就可以通过builder的 getProduct() 方法获得最终的产品

1.3 代码

  • 产品类
    • public class Computer {
          private String cpu;//必须
          private String ram;//必须
          private int usbCount;//可选
          private String keyboard;//可选
          private String display;//可选
      
          public Computer(String cpu, String ram) {
              this.cpu = cpu;
              this.ram = ram;
          }
          public void setUsbCount(int usbCount) {
              this.usbCount = usbCount;
          }
          public void setKeyboard(String keyboard) {
              this.keyboard = keyboard;
          }
          public void setDisplay(String display) {
              this.display = display;
          }
          @Override
          public String toString() {
              return "Computer{" +
                      "cpu='" + cpu + '\'' +
                      ", ram='" + ram + '\'' +
                      ", usbCount=" + usbCount +
                      ", keyboard='" + keyboard + '\'' +
                      ", display='" + display + '\'' +
                      '}';
          }
      }
  • 建造者类
    • 抽象类:抽象的建造者
      • public abstract class ComputerBuilder {
            public abstract void setUsbCount();
            public abstract void setKeyboard();
            public abstract void setDisplay();
        
            public abstract Computer getComputer();    //这个方法必须有
        }
    • 真实建造者类(苹果,联想)
      • public class MacComputerBuilder extends ComputerBuilder {    //苹果电脑构建者类
            private Computer computer;
            public MacComputerBuilder(String cpu, String ram) {
                computer = new Computer(cpu, ram);
            }
            @Override
            public void setUsbCount() {
                computer.setUsbCount(2);
            }
            @Override
            public void setKeyboard() {
                computer.setKeyboard("苹果键盘");
            }
            @Override
            public void setDisplay() {
                computer.setDisplay("苹果显示器");
            }
            @Override
            public Computer getComputer() {
                return computer;
            }
        }
        
        public class LenovoComputerBuilder extends ComputerBuilder {    //联想电脑构建者类
            private Computer computer;
            public LenovoComputerBuilder(String cpu, String ram) {
                computer=new Computer(cpu,ram);
            }
            @Override
            public void setUsbCount() {
                computer.setUsbCount(4);
            }
            @Override
            public void setKeyboard() {
                computer.setKeyboard("联想键盘");
            }
            @Override
            public void setDisplay() {
                computer.setDisplay("联想显示器");
            }
            @Override
            public Computer getComputer() {
                return computer;
            }
        }
  • 指导者类 Director
    • public class ComputerDirector {
          public void Construct(ComputerBuilder builder){
              builder.setUsbCount();
              builder.setDisplay();
              builder.setKeyboard();
          }
      }
  • 客户端调用
    • public static void main(String[] args) {
              ComputerDirector director=new ComputerDirector();//1
              ComputerBuilder builder=new MacComputerBuilder("I5处理器","三星125");//2
              director.makeComputer(builder);//3
              Computer macComputer=builder.getComputer();//4
              System.out.println("mac computer:"+macComputer.toString());
      
              ComputerBuilder lenovoBuilder=new LenovoComputerBuilder("I7处理器","海力士222");
              director.makeComputer(lenovoBuilder);
              Computer lenovoComputer=lenovoBuilder.getComputer();
              System.out.println("lenovo computer:"+lenovoComputer.toString());
      }

2. 简化版 建造者模式

这种方式不需要 ConcreteBuilder

2.1 如何实现

  • 在Computer 中创建一个静态内部类 Builder,然后将Computer 中的参数都复制到Builder类中。
  • 在Computer中创建一个private的构造函数,参数为Builder类型
  • 在Builder中创建一个public的构造函数,参数为Computer中必填的那些参数,cpu 和ram。
  • 在Builder中创建设置函数,对Computer中那些可选参数进行赋值,返回值为Builder类型的实例
  • 在Builder中创建一个build()方法,在其中构建Computer的实例并返回

2.2 代码

  • public class Computer {
        private final String cpu;//必须
        private final String ram;//必须
        private final int usbCount;//可选
        private final String keyboard;//可选
        private final String display;//可选
    
        private Computer(Builder builder){
            this.cpu=builder.cpu;
            this.ram=builder.ram;
            this.usbCount=builder.usbCount;
            this.keyboard=builder.keyboard;
            this.display=builder.display;
        }
        public static class Builder{
            private String cpu;//必须
            private String ram;//必须
            private int usbCount;//可选
            private String keyboard;//可选
            private String display;//可选
    
            public Builder(String cup,String ram){
                this.cpu=cup;
                this.ram=ram;
            }
    
            public Builder setUsbCount(int usbCount) {
                this.usbCount = usbCount;
                return this;
            }
            public Builder setKeyboard(String keyboard) {
                this.keyboard = keyboard;
                return this;
            }
            public Builder setDisplay(String display) {
                this.display = display;
                return this;
            }        
            public Computer build(){
                return new Computer(this);
            }
        }
      //省略getter方法
    }
  • 如何调用
    • Computer computer=new Computer.Builder("因特尔","三星")
                      .setDisplay("三星24寸")
                      .setKeyboard("罗技")
                      .setUsbCount(2)
                      .build();

3. 总结

  • 建造者模式唯一区别于工厂模式的是针对复杂对象的创建。也就是说,如果创建简单对象,通常都是使用工厂模式进行创建,而如果创建复杂对象,就可以考虑使用建造者模式
  • 如果创建的产品种类只有一种,只需要一个具体建造者,这时可以省略掉抽象建造者,甚至可以省略掉指挥者角色。

Reference

https://zhuanlan.zhihu.com/p/58093669

http://c.biancheng.net/view/1354.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值