建造者模式
一、模式名
建造者, Builder
二、解决的问题
我们每天都在创建对象、使用对象,一般简单对象直接通过new创建即可。如果要创建的对象很复杂,或者创建对象的方式有很多,我们怎样才能做到高内聚低耦合?这时建造者模式就派上用场了。建造者模式通过抽象出某个对象的构造过程,具体构造实现交给子类完成,通过引入一个“第三者”,用于组装对象的建造过程,完成对象的构造。
看上去,这个模式和模板方法很类似,模板方法是通过父类确定解决过程,解决过程中的具体操作由子类实现。在模板方法中,父类相当于这里的第三者,负责确定具体的解决方案。这就是模板方法和建造者模式的区别。
建造者模式有两个主要的优点:
1. 复用,抽象出某个实体的构造过程方法,交给具体子类实现,通过引入“看工”,组装具体的构造过程;
2.隔离,一般客户端只需要使用“看工”完成具体实体的构造,不需要考虑看工使用了哪一个子类完成构造,有利于程序的扩展。
三、解决方案
构造者模式的UML图如下图所示。
可以看到,定义了一个抽象类或接口Builder,其中声明了在构造过程中可能会用到的方法,还有一个Director类,即为“看工”,用于组装构造过程,对外提供构造实体的方法。
代码如下:
package com.libaoshen.java.study.java.base; /** * @author libaoshen * @since 2020/1/13 20:18:17 */ public class Test { } public class BuilderTest { public static void main(String[] args) { Builder countryBuilder = new CountryBuilder(); Builder cityBuilder = new CityBuilder(); Director director = new Director(countryBuilder); Director director2 = new Director(cityBuilder); director.construct(); director2.construct(); } } // 看工 class Director { private Builder builder; public Director(Builder builder) { this.builder = builder; } public void construct() { builder.start(); builder.buildBase(); builder.buildMiddle(); builder.buildTop(); builder.decorate(); builder.end(); } } // 建造者抽象类 abstract class Builder { abstract void start(); abstract void buildBase(); abstract void buildMiddle(); abstract void buildTop(); abstract void decorate(); abstract void end(); } // 农村建房 class CountryBuilder extends Builder { @Override void start() { System.out.println("开始建楼"); } @Override void buildBase() { System.out.println("打水泥地基"); } @Override void buildMiddle() { System.out.println("修三层砖楼"); } @Override void buildTop() { System.out.println("裸露屋顶"); } @Override void decorate() { System.out.println("简单装修"); } @Override void end() { System.out.println("完成建楼"); } } // 城市建房 class CityBuilder extends Builder { @Override void start() { System.out.println("开始建楼"); } @Override void buildBase() { System.out.println("修大理石地基"); } @Override void buildMiddle() { System.out.println("建欧式小三楼"); } @Override void buildTop() { System.out.println("修建阁楼"); } @Override void decorate() { System.out.println("豪华装修"); } @Override void end() { System.out.println("放置通风"); } }
建造者模式实践
class Request { private String requestMethod; private String requestUrl; private String requestHeader; private String requestBody; public Request(String requestHeader, String requestUrl, String requestBody, String requestMethod) { this.requestUrl = requestUrl; this.requestBody = requestBody; this.requestHeader = requestHeader; this.requestMethod = requestMethod; } // 静态方法,获取builder对象 public static RequestBuilder builder() { return new RequestBuilder(); } @Override public String toString() { return "Request{" + "requestMethod='" + requestMethod + '\'' + ", requestUrl='" + requestUrl + '\'' + ", requestHeader='" + requestHeader + '\'' + ", requestBody='" + requestBody + '\'' + '}'; } // 定义static builder public static class RequestBuilder { private String requestMethod; private String requestUrl; private String requestHeader; private String requestBody; public RequestBuilder requestMethod(String requestMethod) { this.requestMethod = requestMethod; return this; } public RequestBuilder requestUrl(String requestUrl) { this.requestUrl = requestUrl; return this; } public RequestBuilder requestHeader(String requestHeader) { this.requestHeader = requestHeader; return this; } public RequestBuilder requestBody(String requestBody) { this.requestBody = requestBody; return this; } public Request build() { return new Request(this.requestHeader, this.requestUrl, this.requestBody, this.requestMethod); } } }
常见应用场景:
1. ElasticSearch Java API中用于构造查询请求