首页 > 编程语言 >Java设计模式 —— 建造者模式

Java设计模式 —— 建造者模式

时间:2022-10-03 18:33:32浏览次数:51  
标签:Product Java Builder builder 建造 abstract void 设计模式 public

8 建造者模式

8.1 建造者模式概述

Builder Pattern:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

建造者模式可以将部件本身和它们的组装过程分开,关注如何一步一步地创建一个包含多个组成部分的复杂对象,用户只需指定复杂对象的类型即可得到该对象,而无须知道其内部的具体构造细节。

建造者模式结构图如下:

8.2 建造者模式实现

8.2.1 抽象建造者类

public abstract class Builder {
  protected Product product = new Product();
  
  public abstract void buildPartA();
  public abstract void buildPartB();
  public abstract void buildPartC();
  
  // 返回产品对象
  public Product getProduct() {
    return product;
  }
}

8.2.2 具体建造者类

public class ConcreteBuilder extends Builder {
  public void buildPartA(PartA partA) {
    product.setPartA(partA);
  }
  
  public void buildPartB(PartB partB) {
    product.setPartB(partB);
  }
  
  public void buildPartC(PartC partC) {
    product.setPartB(partC);
  }
}

8.2.3 具体产品类

public class Product {
  private PartA partA;
  private PartB partB;
  private PartC partC;
  
  /**
   * get and set methods
   */
}

8.2.4 指挥者类

引入该类主要有两个作用:

  • 隔离了客户端与创建过程
  • 控制产品对象的创建过程
public class Director {
  private Builder builder;
  
  public Director(Builder builder) {
    this.builder = builder;
  }
  
  public void setBuilder(Builder builder) {
    this.builder = builder;
  }
  
  public Product construct() {
    builder.buildPartA();
    builder.buildPartB();
    builder.buildPartC();
    return builder.getProduct();
  }
}

8.2.5 客户端调用

对于客户端而言,只需要关注具体建造者的类型,无须关心产品对象的具体创建过程。

public class Client {
  Builder builder = new ConcreteBuilder();
  Director director = new Director(builder);
  Product product = director.construct();
}

8.3 指挥者类的变化形式

指挥者类是建造者模式的重要组成部分,简单的 Director 类用于指导具体创建如何创建产品,它按一定顺序调用 Builder 中的各个方法,控制先后顺序,并向客户端返回一个完整的产品对象。

8.3.1 省略指挥者类

为了简化系统结构,某些情况下可以将指挥者类和抽象建造者类进行合并,在 Builder 中提供构建复杂产品对象的 construct() 方法。由于 Builder 通常为抽象类,无法直接实例化,因此可以将 construct() 方法定义为静态方法,以便客户端可以直接调用。

public abstract class Builder {
  protected static Product product = new Product();
  
  public abstract void buildPartA();
  public abstract void buildPartB();
  public abstract void buildPartC();
  
  // 返回产品对象
  public static Product construct(Builder builder) {
    builder.buildPartA();
    builder.buildPartB();
    builder.buildPartC();
    
    return product;
  }
}


// 客户端调用
public class Client {
  Builder builder = new ConcreteBuilder();
  Product product = Builder.construct(builder);
}

由于静态变量是被所有实例所共享的,在内存中只有一个副本,因此上述方法只能创建一个 Product 对象。可以做如下改进:

public abstract class Builder {
  protected Product product = new Product();
  
  public abstract void buildPartA();
  public abstract void buildPartB();
  public abstract void buildPartC();
  
  // 返回产品对象
  public Product construct() {
    this.buildPartA();
    this.buildPartB();
    this.buildPartC();
    
    return product;
  }
}


// 客户端调用
Builder builder = new ConcreteBuilder();
Product product = builder.construct();

以上两种方法对 Director 类的省略方式都不影响系统的灵活性和扩展性,同时还简化了系统结构,但是加重了抽象建造者类的职责。如果 construct() 方法较为复杂,待构建产品组成较多,还是应该不省略指挥者类

8.3.2 钩子方法

建造者模式可以通过 Director 类更加精细的控制产品的创建过程,例如增加一类钩子方法来控制是需要对某个 buildPartX() 方法进行调用。

public abstract class Builder {
  protected Product product = new Product();
  
  public abstract void buildPartA();
  public abstract void buildPartB();
  public abstract void buildPartC();
  
  // 钩子方法, 子类可以覆盖该方法
  public boolean isBuildPartA() {
    return false;
  }
  
  public Product construct() {
    return product;
  }
}
public class Director {
  public Product construct(Builder builder) {
    if (builder.isBuildPartA()) {
      builder.buildPartA();
    }
    builder.buildPartB();
    builder.buildPartC();
    
    Product product = builder.construct();
    return product;
  }
}

8.4 建造者模式优/缺点

建造者模式优点主要如下:

  • 客户端无须知道产品内存的创建细节,将产品本身与创建过程解耦,使得相同的创建过程可以创建不同的产品对象
  • 每一个具体的建造者都相对独立,与其他具体建造者无关,可以很方便的增加或删除具体建造者
  • 更加精细地控制产品的创建过程,将复杂产品的创建步骤分解在不同的方法中

建造者模式缺点主要如下:

  • 如果产品的内部变化复杂,可能会导致需要定义很多具体的建造者类来实现这种变化,导致系统很庞大

标签:Product,Java,Builder,builder,建造,abstract,void,设计模式,public
From: https://www.cnblogs.com/ylyzty/p/16750975.html

相关文章

  • java网络编程--2 IP,端口,通信协议,TCP/UDP对比
    java网络编程--2IP,端口,通信协议,TCP/UDP对比1.3、IPip地址:InetAddress唯一定位一台网络上的计算机127.0.0.1:本机localhostIP地址的分类ipv4/ipv6IPV4......
  • java_day05
    Java流程控制用户交互ScannerJava给我们提供了一个工具类,让我们可以获取用户的输入。java.util.Scanner是Java5的新特性基本语法Scanners=newScanner(System.......
  • java_day04
    Java基础包机制包实质上就是文件夹一般利用公司域名倒置作为包名JavaDocjavadoc命令是用来生成自己的API文档的参数信息@author作者名@version版本号@since......
  • 抽象类及模板设计模式
    1基本介绍当父类的某些方法,需要声明,但是又不确定如何实现时,可以将其声明为抽象方法,那么这个类就是抽象类当父类的一些方法不能确定时,可以用abstract关键字来修饰该方......
  • Java SE 宋红康 days04-高级篇-网络编程
    1.Socket:端口号与IP地址的组合得出一个网络套接字;2. 计算机网络中实现通信必须有一些约定,即通信协议:对速率、传输代码、代码结构、传输控制步骤、出错控制等制定标准。......
  • 快速排序 Java代码展示
    我们快速排序的图解放在下面,有一些重复的动作就省略。java代码如下:/***@author:阿久*快速排序*/publicclassSnackOrder{publicstaticvoidmain(Str......
  • JAVA对象的内存解析
    堆(Heap):此内存区域用来存放对象实例栈(Stack): 存储局部变量,局部变量存储有数据类型(boolean,byte,int,short,int,float,long,double)、对象引用(reference类型,是对象在堆内......
  • javaScript--5 javascript json字符串转换
      <!DOCTYPEhtml><html><head><title>JavaScript对象转JSON字符串</title></head><body><script>varjsonObj={"userId":"admin",......
  • JadConfig 注解驱动的java 配置管理包
    JadConfig是graylog开源的一个基于注解驱动的java配置管理包,graylogserver对于配置的管理就是使用了此包JadConfig使用比较简单,但是功能还是很强大的,配置包含了校验......
  • 微软出品自动化神器Playwright,不用写一行代码(Playwright+Java)系列(三) 之 手把手带你
    写在前面官方给的栗子是Junit,但是我还是用TestNG来进行脚本的编写,这里只分享思路,不管是哪个测试框架基本思路都是一样的,喜欢用官方的Junit的,建议查看​​官方文档​​。如何......