设计模式-建造者模式(Builder Pattern)
1 概述
1.1 定义
建造者模式(Builder Pattern)将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。也就是说,需要创建的对象所需要的组件的创建和由这些组件组合成对象的装配完全独立分离,并且不同的组合方式会产生不同表示的对象。
1.2 适用范围
- 需要生成的产品的内部结构复杂。每个内部成分本身也可以是对象,也可以仅仅是目标对象的一个组成成分。
- 需要生成的产品属性相互依赖。建造模式可以强制实行一种分步骤的建造过程,因此产品对象的一个属性必须在另一个属性被赋值后进行赋值。比如:我想打乒乓球,必须先找到商店,然后买到球拍和球,然后找到球案才可以打球。中间的顺序不允许打乱。
- 在创建对象过程中会使用系统中其他的一些对象,这些对象在产品对象创建过程中不易得到。
1.3 作用
- 使得产品内部表象可以独立的变化。使用该模式可以使客户端不必知道产品内部组成的细节。
- 每一个Builder都相对独立,与其他Builder无关。
- 最终产品易于控制。
1.3 角色
- builder:为创建一个产品对象的各个部件指定抽象接口。
- ConcreteBuilder:实现Builder的接口以构造和装配该产品的各个部件,定义并明确它所创建的表示,并 提供一个检索产品的接口。
- Director:构造一个使用Builder接口的对象。
- Product:表示被构造的复杂对象。ConcreteBuilder创建该产品的内部表示并定义它的装配过程,包含定义组成部件的类,包括将这些部件装配成最终产品的接口。
1.3 优缺点
优点 | 缺点 |
---|---|
建造者独立,易扩展; 便于控制细节风险。 | 产品必须有共同点,范围有限制;如内部变化复杂,会有很多的建造类。 |
2 示例
2.1 示例一:对应以上角色
2.1.1 角色代码编写
Product.java:需要创建的对象
public class Product {
private String part1;
private String part2;
private String part3;
private String part4;
public String getPart4() {
return part4;
}
public void setPart4(String part4) {
this.part4 = part4;
}
public String getPart1() {
return part1;
}
public void setPart1(String part1) {
this.part1 = part1;
}
public String getPart2() {
return part2;
}
public void setPart2(String part2) {
this.part2 = part2;
}
public String getPart3() {
return part3;
}
public void setPart3(String part3) {
this.part3 = part3;
}
@Override
public String toString() {
return "Product{" +
"part1='" + part1 + '\'' +
", part2='" + part2 + '\'' +
", part3='" + part3 + '\'' +
", part4='" + part4 + '\'' +
'}';
}
}
Builder.java
public interface Builder {
void buildPart1();
void buildPart2();
void buildPart3();
void buildPart4();
Product buildProduct();
}
ConcreteBuilder:具体建造者
public class ConcreteBuilder implements Builder {
private Product product;
public ConcreteBuilder() {
this.product = new Product();
}
@Override
public void buildPart1() {
product.setPart1("part1");
}
@Override
public void buildPart2() {
product.setPart2("part2");
}
@Override
public void buildPart3() {
product.setPart3("part3");
}
@Override
public void buildPart4() {
product.setPart4("part4");
}
@Override
public Product buildProduct() {
return product;
}
}
Director:导演
public class Director {
/**
* 创建一个完整的产品
* @param builder
* @return
*/
public Product completeProduct(Builder builder) {
builder.buildPart1();
builder.buildPart2();
builder.buildPart3();
builder.buildPart4();
return builder.buildProduct();
}
/**
* 创建一个缺少部件,由下到上的产品
* @param builder
* @return
*/
public Product nonCompleteProduct(Builder builder) {
builder.buildPart4();
builder.buildPart3();
builder.buildPart2();
return builder.buildProduct();
}
}
2.1.2 测试
Main.java:测试代码
public class Main {
public static void main(String[] args) {
Director director = new Director();
Product product1 = director.completeProduct(new ConcreteBuilder());
Product product2 = director.nonCompleteProduct(new ConcreteBuilder());
System.out.println(product1);
System.out.println(product2);
}
}
输出结果
Product{part1='part1', part2='part2', part3='part3', part4='part4'}
Product{part1='null', part2='part2', part3='part3', part4='part4'}
2.2 实例二:封装Http JSON对象
建造者模式在使用过程中可以演化出多种形式。
2.2.1 角色代码编写
JSONResponse .java:需要生成的对象
public class JSONResponse {
/**
* 返回状态码
*/
private int code;
/**
* 返回信息
*/
private String message;
/**
* 返回携带的对象,可以携带异常
*/
private Object object;
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Object getObject() {
return object;
}
public void setObject(Object object) {
this.object = object;
}
@Override
public String toString() {
return "JSONResponse{" +
"code=" + code +
", message='" + message + '\'' +
", object=" + object +
'}';
}
}
JSONResponseBuilder .java
public interface JSONResponseBuilder {
/**
* 创建状态码
* @return
*/
JSONResponseBuilder code(int code);
/**
* 创建返回信息
* @return
*/
JSONResponseBuilder message(String message);
/**
* 创建携带返回对象
* @return
*/
JSONResponseBuilder object(Object o);
/**
* 创建JSONResponse对象
* @return
*/
JSONResponse build();
}
ConcreteJSONResponseBuilder .java:具体建造者
public class ConcreteJSONResponseBuilder implements JSONResponseBuilder {
private JSONResponse response;
public ConcreteJSONResponseBuilder() {
this.response = new JSONResponse();
}
@Override
public JSONResponseBuilder code(int code) {
response.setCode(code);
return this;
}
@Override
public JSONResponseBuilder message(String message) {
response.setMessage(message);
return this;
}
@Override
public JSONResponseBuilder object(Object o) {
response.setObject(o);
return this;
}
@Override
public JSONResponse build() {
return response;
}
}
JSONResponseDiretor .java:导演
public class JSONResponseDiretor {
/**
* 创建成功返回对象
* @param builder
* @param o
* @return
*/
public JSONResponse buidSuccessJSONResponse(JSONResponseBuilder builder,Object o) {
return builder.code(200).message("success").object(o).build();
}
/**
* 创建失败返回对象
* @param builder
* @param e
* @return
*/
public JSONResponse buidSuccessJSONResponse(JSONResponseBuilder builder,Exception e) {
return builder.code(500).message("error").object(e).build();
}
}
2.2.2 测试
Main.java:测试代码
public class Main {
public static void main(String[] args) {
JSONResponseDiretor diretor = new JSONResponseDiretor();
JSONResponse response1 = diretor.buidSuccessJSONResponse(new ConcreteJSONResponseBuilder(), 1);
JSONResponse response2 = diretor.buidSuccessJSONResponse(new ConcreteJSONResponseBuilder(), new Exception("错误"));
//拓展:省略导演,创建不携带返回结果对象
JSONResponse response3 = new ConcreteJSONResponseBuilder().code(100).message("不携带返回结果").build();
System.out.println(response1);
System.out.println(response2);
System.out.println(response3);
}
}
只有把命运掌握在自己手中,从今天起开始努力,即使暂时看不到希望,也要相信自己。因为比你牛几倍的人,依然在努力。