设计模式–builder 模式

说明

  1. @author JellyfishMIX - github / blog.jellyfishmix.com
  2. LICENSE GPL-2.0
  3. 本文默认已经知道了 builder 模式的使用场景和意义,只分析 builder 模式的实现。
  4. 直接通过 demo 讲更清晰。

两种传统的构造实例的方式

我们有一个 Computer 类,属性如下,构造实例时分必须和可选。

public class Computer {// 必须private String cpu;// 必须private String ram;// 可选private int usbCount;// 可选private String keyboard;// 可选private String display;
}

不用 builder 设计模式,通常有两种传统的构造实例的方式:

第一种折叠构造函数模式(telescoping constructor pattern),即编写多个构造方法,每个构造方法中必须的属性必有,可选属性依次增加:

public class Computer {...public Computer(String cpu, String ram) {this(cpu, ram, 0);}public Computer(String cpu, String ram, int usbCount) {this(cpu, ram, usbCount, "罗技键盘");}public Computer(String cpu, String ram, int usbCount, String keyboard) {this(cpu, ram, usbCount, keyboard, "三星显示器");}public Computer(String cpu, String ram, int usbCount, String keyboard, String display) {this.cpu = cpu;this.ram = ram;this.usbCount = usbCount;this.keyboard = keyboard;this.display = display;}
}

第二种 JavaBean 模式,就是一堆 getter&setter:

public class Computer {...public String getCpu() {return cpu;}public void setCpu(String cpu) {this.cpu = cpu;}public String getRam() {return ram;}public void setRam(String ram) {this.ram = ram;}public int getUsbCount() {return usbCount;}
...
}

两种传统构造实例方式的缺点

  1. 可读性差,使用时代码量多。
  2. JavaBean 的 getter&setter 使用时不是原子性的,属性是分步设置的,在构建过程中对象的状态可能发生变化,造成问题。

简化版 builder 模式

为了便于理解,先看简化版 builder 模式。还是要构建一个 Computer 实例,构造实例时属性分必须和可选。

public class Computer {// 必须private String cpu;// 必须private String ram;// 可选private int usbCount;// 可选private String keyboard;// 可选private 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方法
}
  1. 在 Computer 中编写一个静态内部类 Builder,然后将 Computer 中的属性都复制到 Builder 类中。
  2. 在 Computer 中创建一个 private 的构造函数,入参为 Builder 类型。后面 builder 实例在设置好属性后,会把 builder 实例通过这个构造方法传入,构造出 computer 实例。
  3. 在 Builder 中编写一个 public 的构造函数,入参为 Computer 中必须的那些属性,cpu 和 ram。
  4. 在 Builder 中编写 setter 方法,对 Computer 中那些可选属性进行赋值,返回值为 Builder 类型的实例。
  5. 在 Builder 中编写一个 build 方法,在其中构建 Computer 的实例并返回。

经典的 Builder 模式

上面简化版 builder 模式便于理解,经典的 builder 模式有 4 个角色。

  1. Product 类: 最终要生成的对象,例如 computer 实例。

  2. Builder 抽象类(或使用接口代替)。定义了构建 Product 的构建用抽象方法,其 Builder 实现类需要实现这些构建用方法。还会拥有一个用来返回最终产品的方法 Product getProduct()。

  3. ConcreteBuilder: Builder 的实现类,实现 Builder 的抽象方法,编写此种 Builder 实现的方法。

  4. Director: 决定如何使用 Builder 实现类提供的构建用方法。拥有一个负责组装的方法 void construct(Builder builder),在这个方法中通过组织并调用 builder 的方法,可以设置 builder。设置完成后,通过 builder 的构建方法 getProduct() 获得最终的产品。

Product 类

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;}@Overridepublic String toString() {return "Computer{" +"cpu='" + cpu + '\'' +", ram='" + ram + '\'' +", usbCount=" + usbCount +", keyboard='" + keyboard + '\'' +", display='" + display + '\'' +'}';}
}

Builder 抽象类

public abstract class ComputerBuilder {public abstract void setUsbCount();public abstract void setKeyboard();public abstract void setDisplay();public abstract Computer getComputer();
}

ConcreteBuilder: Builder 的实现类–苹果电脑 Builder

public class MacComputerBuilder extends ComputerBuilder {private Computer computer;public MacComputerBuilder(String cpu, String ram) {computer = new Computer(cpu, ram);}@Overridepublic void setUsbCount() {computer.setUsbCount(2);}@Overridepublic void setKeyboard() {computer.setKeyboard("苹果键盘");}@Overridepublic void setDisplay() {computer.setDisplay("苹果显示器");}@Overridepublic Computer getComputer() {return computer;}
}

ConcreteBuilder: Builder 的实现类–联想电脑 Builder

public class LenovoComputerBuilder extends ComputerBuilder {private Computer computer;public LenovoComputerBuilder(String cpu, String ram) {computer=new Computer(cpu,ram);}@Overridepublic void setUsbCount() {computer.setUsbCount(4);}@Overridepublic void setKeyboard() {computer.setKeyboard("联想键盘");}@Overridepublic void setDisplay() {computer.setDisplay("联想显示器");}@Overridepublic Computer getComputer() {return computer;}
}

Director

public class ComputerDirector {public void makeComputer(ComputerBuilder builder){builder.setUsbCount();builder.setDisplay();builder.setKeyboard();}
}

使用

  1. 首先创建一个 director。
  2. 然后创建一个 builder。
  3. 接着使用 director 操作 builder,对 builder 进行组装。
  4. builder 组装完毕后,使用 builder 构建方法创建产品实例。
public static void main(String[] args) {// 1ComputerDirector director=new ComputerDirector();// 2ComputerBuilder builder=new MacComputerBuilder("I5处理器","三星125");// 3director.makeComputer(builder);// 4Computer macComputer=builder.getComputer();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());
}

输出:

mac computer:Computer{cpu='I5处理器', ram='三星125', usbCount=2, keyboard='苹果键盘', display='苹果显示器'}
lenovo computer:Computer{cpu='I7处理器', ram='海力士222', usbCount=4, keyboard='联想键盘', display='联想显示器'}

设计模式--builder 模式相关推荐

  1. 设计模式-Builder模式

    目录 一个例子(做汤) 人工做汤 机器做汤(使用Builder模式) 优缺点 优点 缺点 Builder模式属于创建型模式. 它是将一个复杂对象的构建过程隐藏起来,让使用者只关系自己要生成什么样的对象 ...

  2. Java设计模式——Builder模式

    前言 之前写Android程序的时候,经常会用到Dialog(对话框)这个控件.我们在使用Dialog,比如AlertDialog的时候就用到了这里要说明的Builder模式.现在我们来看一下这样的一 ...

  3. 设计模式 —— Builder 模式

    文章目录 1 Builder 模式的核心思想 2 第一种 Builder 模式 3 第一种模式的困惑 4 第二种 Builder 模式 5 第二种 Builder 模式见解 6 参考 1 Builde ...

  4. Java 常用设计模式 -- Builder模式

    Builder模式是在Java中最流行的模式之一.它很简单,有助于保持对象不可变,并且可以使用Project Lombok的@Builder或Immutables等工具生成,仅举几例. 模式的流畅变体 ...

  5. java的设计模式 - Builder模式

    Builder 模式的目的? 构造对象的方式过于复杂,不如将之抽离出来.比如,构造器参数过多 这样说也有点抽象,举个例子吧. 举个例子 比如 非常热门的消息队列RabbitMQ 的 AMQP.Basi ...

  6. GOF 设计模式 builder模式笔记

    Builder(生成器) 意图:将一个复杂对象的构建与它的表示相分离,使得同样的构建过程可以创建不同的表示. 在以下情况使用Builder模式 当创建复杂的对象应该独立于该对象的组成部分以及它们的装配 ...

  7. Java设计模式-Builder模式

    Builder模式是将一个复杂对象的创建和表示分离,使同样的创建过程可以创建不同的表示.它属于建造类模式. 一般来说,如果一个对象的创建比较复杂,超出了构造方法所能包含的范围,就可以使用工厂模式和Bu ...

  8. 设计模式 builder模式

    也是属于对象创建类模式.使用的一般情况是,需要完成一个复杂的对象创建工作,工作通常由各个部分的子对象用一定的算法构成,比如step1,step2,step3,步骤内部常常发生剧烈的变化,但是组合在一起 ...

  9. 设计模式-Builder模式(构建者模式)

    目录 构建者模式是什么? 为什么要用构建者模式? 构建者模式是什么? 简单来说,就是用于组装具有复杂结构的实例的模式. 什么意思呢?先来看个例子,比如现在有一个类TextBuilder用来创建一个文本 ...

最新文章

  1. TextLink的空格使用
  2. 转载 :28 个 Unix/Linux 的命令行神器
  3. Ext2.0布局类初探
  4. vue移动端下拉切换页面_Vue实现移动端页面切换效果
  5. PAT甲级1075 PAT Judge:[C++题解]排序、结构体
  6. python中sorted_Python中sorted()方法的用法
  7. delete if only one note header
  8. 2007高考:考生要根据家庭经济条件慎重填报按办学成本收费的高校及专业
  9. CF1592D Hemose in ICPC ?
  10. 阿里云对象存储OSS与文件存储NAS的区别
  11. CCF NOI1072 爬楼梯
  12. excel小写转大写公式_喂!这边居然有演示的Excel快捷键!
  13. [Ubuntu] 无法修正错误,因为您要求某些软件包保持现状,就是它们破坏了软件包间的依赖关系
  14. 简单理解以太网和令牌环网【区别】
  15. C语言中TC20是什么意思,c语言tc20下载
  16. 小程序使用wxs处理手机号
  17. STM32F103_study69_The punctual atoms(STM32 SPI communication principle and configuration)
  18. linux中cp: omitting directory `XXX' 问题解决
  19. 关于‘go list‘ failed with: error obtaining VCS status error obtaining VCS status: exit status 128问题的解决
  20. 职场教育小课堂:信息时代的管理方法

热门文章

  1. 使用zxing 解析图片中的二维码
  2. MAC地址,IP地址和ARP协议
  3. GB2312、GB18030、GBK、UNICODE、BIG5之间兼容关系如何?
  4. URL 重写的常见用法
  5. Win8安装教程!笔记本用U盘安装Win8只需三步
  6. C语言程序设计教程(第三版)李凤霞 第一章课后习题答案
  7. 新氧“自律破圈” 医美新生态而立时
  8. HEIF格式怎么转换图片?教你一个小技巧
  9. 排序算法——简单选择排序(PythonJava)
  10. 开始读《C专家编程》