介绍
定义
将一个复杂对象的构建和它的表示分离开,使得同样的构建过程可以创建不同的表示。
角色
Builder : 构建者接口,用于规范产品的各个组成部分,并进行抽象,一般独立于应用程序的逻辑。
Concrete Builder : 实现抽象建造者中定义的所有方法,并且返回一个组建好的产品实例。
Product : 建造者中的复杂对象,一个系统中会有多于一个的产品类,这些产品类并不一定有共同的接口,完全可以是不相关联的。
Director:负责安排已有模块的顺序,然后告诉Builder开始建造。
buidler模式的侧重点是在创建对象,也就是new对象方面
场景
构建者模式一般用在构建流程或者组成部件固定的场合,将这些部件分开构建成为组件对象,再将这些组件对象整合成为目标对象。
它属于创建类模式,一般来说,如果一个对象的构建比较复杂,超出了构造函数所能包含的范围,就可以使用工厂模式和Builder模式,相对于工厂模式会产出一个完整的产品,Builder应用于更加复杂的对象的构建,甚至只会构建产品的一个部分。
实践
常规模式
组装台式电脑的情况,我们可以分别购买主板、CPU、内存、硬盘等部件,然后将这些部件组装在一起就形成了一台完整的电脑。参照如下类图可以比较明显了了解编码如何实现构建者模式:
Builder:构建接口 public interface Builder {
void build_CPU();
void build_mainboard();
void build_memory();
void build_DISK();
void build_power();
Computer getComputer();
}
ComputerBuilder:电脑构建类 public class ComputerBuilder implements Builder {
private Computer computer = new Computer();
@Override
public void build_CPU() {
computer.parts.add("采用INTEL的CPU");
}
@Override
public void build_mainboard() {
computer.parts.add("采用大型主版");
}
@Override
public void build_memory() {
computer.parts.add("采用8G内存");
}
@Override
public void build_DISK() {
computer.parts.add("采用1TB固态硬盘");
}
@Override
public void build_power() {
computer.parts.add("采用XXX电源");
}
@Override
public Computer getComputer() {
return computer;
}
}
Director:组装类 public class Director {
public void construct(Builder builder){
builder.build_CPU();
builder.build_mainboard();
builder.build_memory();
builder.build_DISK();
builder.build_power();
}
}
Computer:成品类 import java.util.*;
public class Computer {
List parts = new ArrayList();
//ignore other method ...
}
变种模式
lombok的@Builder就是这种模式:提供在设计数据实体时,对外保持private setter。这种链式调用的方式,用起来很方便,自己写的话可以这样写:
package xin.demo;
/**
*
* builder 模式示例代码
*
*
* @author michael_merry@163.com
*/
public class Person {
private String name;
private int age;
private String location;
private String job;
// 忽略 getter,自行补充
// 不对外提供setter ...
// 所有的构建从这个静态的builder方法开始链式调用
public static PersonBuilder builder() {
return new PersonBuilder();
}
Person(PersonBuilder builder) {
this.name = builder.name;
this.location = builder.location;
this.job = builder.job;
this.age = builder.age;
}
public static class PersonBuilder {
private String name;
private int age;
private String location;
private String job;
public PersonBuilder name(String name){
this.name = name;
return this;
}
public PersonBuilder age(int age) {
this.age = age;
return this;
}
public PersonBuilder location(String location) {
this.location = location;
return this;
}
public PersonBuilder job(String job) {
this.job = job;
return this;
}
public Person build() {
return new Person(this);
}
}
public static void main(String[] args) {
System.out.println(Person
.builder()
.name("马老七")
.age(28)
.location("北京市东城区")
.job("沙雕的***")
.build().toString());
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", location='" + location + '\'' +
", job='" + job + '\'' +
'}';
}
}
输出:Person{name='马老七', age=28, location='北京市海淀区', job='沙雕的***'}
参考