该子标题中内容,来源菜鸟教程
将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。
主要解决在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。
一些基本部件不会变,而其组合经常变化的时候。
将变与不变分离开。
建造者独立,易扩展。
便于控制细节风险。
产品必须有共同点,范围有限制。
如内部变化复杂,会有很多的建造类。
需要生成的对象具有复杂的内部结构。
需要生成的对象内部属性本身相互依赖。
与工厂模式的区别是:建造者模式更加关注与零件装配的顺序。
产品对象
复杂的内部属性集合的bean。
本文的例子:Company和CompanyPersonnel对象
抽象构建类
主要用来对产品的属性进行构建
本文的例子:CompanyBuilder对象
具体的构建类
该类实现 【抽象构建类】 ,对产品中的属性进行具体的创建
本文的例子:ATestCompanyBuilder对象
导演类
对产品进行具体的组装。
【具体的构建类】指的是产品中的属性进行构建,
而该类是获取最终的产品对象
本文的例子:Director对象
代码含义
没有复杂业务,简单代码展示,对一个公司和员工的 bean 进行构建。
代码展示
产品对象
公司对象
package com.builderpattern.vo;
import lombok.Data;
import java.util.List;
/**
* @version v1.0
* @Copyright(c): 2020-2020
* @FileName: Company.java
* @Description: 公司对象
* @autho Admin
* @date 2020/1/13 11:35
*/
@Data
public class Company {
/**
* 名称
*/
private String name;
/**
* 公司统一社会信用代码(公司的唯一标识)
*/
private String socialId;
/**
* 企业员工
*/
private List companyPersonnelList;
}
公司员工对象
package com.builderpattern.vo;
import lombok.Data;
/**
* @version v1.0
* @Copyright(c): 2020-2020
* @FileName: CompanyPersonnel.java
* @Description:
* @autho Admin
* @date 2020/1/13 13:54
*/
@Data
public class CompanyPersonnel {
/**
* 员工姓名
*/
private String name;
/**
* 员工编号
*/
private String number;
/**
* 员工年龄
*/
private Integer age;
/**
* 员工性别 0:男 1:女
*/
private String sex;
}
抽象构建类
package com.builderpattern.build;
import com.builderpattern.vo.Company;
import com.builderpattern.vo.CompanyPersonnel;
import java.util.List;
/**
* @version v1.0
* @Copyright(c): 2020-2020
* @FileName: CompanyBuilder.java
* @Description:
* @autho Admin
* @date 2020/1/13 13:56
*/
public abstract class CompanyBuilder {
//创建公司对象(产品)
protected Company company = new Company();
/**
* 产品属性建造 公司名称 可以通过外部传入获取
* @return
*/
public abstract CompanyBuilder buildName(String name);
/**
* 产品属性建造 统一社会信用代码
* @return
*/
public abstract CompanyBuilder buildSocialId();
/**
* 产品属性建造 公司员工集合
* @return
*/
public abstract CompanyBuilder buildPersonnelList();
/**
* 提供一个方法,可以得到产品
* @return
*/
public Company getCompany(){
return company;
}
}
具体的构建类
package com.builderpattern.build;
import com.builderpattern.vo.CompanyPersonnel;
import org.apache.commons.lang3.RandomUtils;
import java.util.ArrayList;
import java.util.List;
/**
* @version v1.0
* @Copyright(c): 2020-2020
* @FileName: ATestCompanyBuilder.java
* @Description: A测试公司建造
* @autho Admin
* @date 2020/1/13 14:04
*/
public class ATestCompanyBuilder extends CompanyBuilder{
public CompanyBuilder buildName(String name) {
company.setName(name);
return this;
}
public CompanyBuilder buildSocialId() {
company.setSocialId("91123123213213211A");
return this;
}
public CompanyBuilder buildPersonnelList() {
ArrayList list = new ArrayList();
for (int i = 0; i < 10; i++) {
CompanyPersonnel companyPersonnel = new CompanyPersonnel();
companyPersonnel.setAge(18+i);
companyPersonnel.setName("测试员工"+(i+1));
companyPersonnel.setNumber(String.valueOf(i+1));
companyPersonnel.setSex(i%2==0?"0":"1");
list.add(companyPersonnel);
}
company.setCompanyPersonnelList(list);
return this;
}
}
导演类
package com.builderpattern.director;
import com.builderpattern.build.CompanyBuilder;
import com.builderpattern.vo.Company;
import lombok.Data;
/**
* @version v1.0
* @Copyright(c): 2020-2020
* @FileName: Director.java
* @Description:
* @autho Admin
* @date 2020/1/13 14:19
*/
@Data
public class Director {
//获取build的基类对象,可以通过有参构造传入
private CompanyBuilder companyBuilder;
public Director(CompanyBuilder companyBuilder){
this.companyBuilder = companyBuilder;
}
//负责公司(产品)对象的创建
public Company construct(String name){
return companyBuilder.buildName(name)
.buildPersonnelList()
.buildSocialId()
.getCompany();
}
}
测试类
package com.builderpattern;
import com.builderpattern.build.ATestCompanyBuilder;
import com.builderpattern.build.CompanyBuilder;
import com.builderpattern.director.Director;
import com.builderpattern.vo.Company;
/**
* @version v1.0
* @Copyright(c): 2020-2020
* @FileName: Test.java
* @Description:
* @autho Admin
* @date 2020/1/13 14:23
*/
public class Test {
public static void main(String[] args) {
//创建建造者
CompanyBuilder builder = new ATestCompanyBuilder();
//通过Director统一组建,并获取产品
Director director = new Director(builder);
Company construct = director.construct("A测试公司");
System.out.println(construct);
}
}
测试结果
Company(name=A测试公司, socialId=91123123213213211A,
companyPersonnelList=
[CompanyPersonnel(name=测试员工1, number=1, age=18, sex=0),
CompanyPersonnel(name=测试员工2, number=2, age=19, sex=1),
CompanyPersonnel(name=测试员工3, number=3, age=20, sex=0),
CompanyPersonnel(name=测试员工4, number=4, age=21, sex=1),
CompanyPersonnel(name=测试员工5, number=5, age=22, sex=0),
CompanyPersonnel(name=测试员工6, number=6, age=23, sex=1),
CompanyPersonnel(name=测试员工7, number=7, age=24, sex=0),
CompanyPersonnel(name=测试员工8, number=8, age=25, sex=1),
CompanyPersonnel(name=测试员工9, number=9, age=26, sex=0),
CompanyPersonnel(name=测试员工10, number=10, age=27, sex=1)])
什么时候使用
本文产品中的成员变量比较少,如果在业务比较复杂,成员变量很多,需要的有参构造方法比较多(而且可能有的成员变量要使用,有的不要使用,很容易乱。使用 set 多了,也会乱),难以维护,就可以使用该模式
附:目录结构
有需要源码的,也可以扫描下方二维码,加我好友,私聊我
- END -
推荐阅读
● 抽象工厂模式
● 装饰者模式
● 工厂模式
● 命令模式-接收者与执行者解耦和
● hexo-详细搭建