目 录
前言
建造者模式是一种创建型设计模式,同类型的还有工厂方法和抽象工厂等。建造者模式可认为大致有两种实现方式,并且在某种程度上可以认为是工厂模式的延伸。工厂模式只关注将单个产品生产出来即可,不关注产品的生产过程/产品的组成部分;建造者模式不仅要将产品生产出来,还要关心产品的生产过程/组成部分。建造者模式的四个角色:产品(Product)、指挥者(Director)、抽象建造者(Builder)和具体建造者(ConcreteBuilder),可用如下类图表示:
建造者模式实践
1. 静态内部类方式
该方式内部有默认实现,略掉了指挥者角色,用户可根据自身需求更改对象内容而无需改变内部构造方式。
1.1 具体实现方式/逻辑
public class ValidteResult {
private String bizNo; //业务编号
private String ruleId; //规则编号
private String ruleContent; //规则内容
private String ruleFlag; //规则类型
private String resultCode; //校验结果
private String resultMsg; //校验结果描述
private Long runTime; //运行时长
public ValidteResult() {
throw new RuntimeException("Initialization is not allowed!");
}
private ValidteResult(Builder builder) {
this.bizNo = builder.bizNo;
this.ruleId = builder.ruleId;
this.ruleContent = builder.ruleContent;
this.ruleFlag = builder.ruleFlag;
this.resultCode = builder.resultCode;
this.resultMsg = builder.resultMsg;
this.runTime = builder.runTime;
}
public static class Builder{
private final String bizNo; //业务编号
private String ruleId; //规则编号
private String ruleContent; //规则内容
private final String ruleFlag; //规则类型
private final String resultCode; //校验结果
private String resultMsg; //校验结果描述
private Long runTime; //运行时长
public Builder(String bizNo, String ruleFlag, String resultCode) {
this.bizNo = bizNo;
this.ruleFlag = ruleFlag;
this.resultCode = resultCode;
}
public Builder buildRuleId(String ruleId) {
this.ruleId = ruleId;
return this;
}
public Builder buildRuleContent(String ruleContent) {
this.ruleContent = ruleContent;
return this;
}
public Builder buildResultMsg(String resultMsg) {
this.resultMsg = resultMsg;
return this;
}
public Builder buildRunTime(Long runTime) {
this.runTime = runTime;
return this;
}
//构建 ValidteResult
public ValidteResult build(){
return new ValidteResult(this);
}
}
}
1.2 客户端调用/测试(ClientTest)
public class ConstructorTest {
@Test
public void testInnerClass(){
ValidteResult.Builder builder = new ValidteResult.Builder("2021001", "1", "R1002");
//根据需求构造不同的 ValidteResult
ValidteResult validteResult0 = builder.build();
ValidteResult validteResult1 = builder.buildResultMsg("已到期,无法办理!").buildRuleContent("期限校验").build();
ValidteResult validteResult2 = builder.buildRunTime(21019210L).buildRuleId("1001").build();
}
}
2. 一般/普通方式
遵循以上贴出的类图,涉及的几类角色一应俱全。
2.1 产品角色(Product)
public class Result {
private String code; //码值
private String msg; //提示信息
private Object data; //数据
public void setCode(String code) {
this.code = code;
}
public void setMsg(String msg) {
this.msg = msg;
}
public void setData(Object data) {
this.data = data;
}
}
2.2 抽象建造者角色(Builder)
public abstract class Builder {
//构造的结果
Result result = new Result();
//结果码
protected abstract void buildCode();
//结果信息
protected abstract void buildMsg();
//结果数据
protected abstract void buildData();
public Result build(){
return result;
}
}
2.3 具体建造者角色(Builder)
2.3.1 具体建造者角色1(CheckResultBuilder)
public class CheckResultBuilder extends Builder {
@Override
protected void buildCode() {
this.result.setCode("1001");
}
@Override
protected void buildMsg() {
this.result.setMsg("校验不通过!");
}
@Override
protected void buildData() {
Map<String, Object> item = new HashMap<String, Object>();
item.put("字段A", "超出限定范围!");
item.put("字段B", "输入内容不合法!");
this.result.setData(item);
}
}
2.3.2 具体建造者角色2(ExecuteResultBuilder)
public class ExecuteResultBuilder extends Builder {
@Override
protected void buildCode() {
this.result.setCode("2002");
}
@Override
protected void buildMsg() {
this.result.setMsg("执行成功!");
}
@Override
protected void buildData() {}
}
2.4 指挥者角色(Director)
public class Director {
private Builder builder = null;
public Director(Builder builder){
this.builder = builder;
}
public Result build(){
this.builder.buildCode();
this.builder.buildMsg();
this.builder.buildData();
return this.builder.build();
}
}
2.5 客户端调用/测试(ClientTest)
public class ConstructorTest {
public static void main(String[] args){
//CheckResult
Builder builder = new CheckResultBuilder();
Director director = new Director(builder);
Result result = director.build();
//ExecuteResult
builder = new ExecuteResultBuilder();
director = new Director(builder);
result = director.build();
}
}
总结
- 对内部类实现方式来说,建造者模式出现常伴随着链式操作,StringBuilder就是一个常见的例子;
- 每个具体的建造者是相互独立的,且指挥者是针对抽象建造者操作,新具体建造者的出现不会影响指挥者原有的结构。