建造者模式
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
类结构图
Director
构建一个使用 Builder 接口的对象。
Builder
为创建一个产品对象各个部件指定的抽象接口。
ConncreteBuilder
具体的建造者,需实现 Builder 接口,构造和装配各个部件。
Product
具体的产品。
代码实现——举个栗子
比如要创建一个人需要创建脑袋、手臂、眼睛等等非常非常多的细节。
/*
* 产品
* /
public class Person {
private String name;
private String body;
private String head;
private String leftArm;
private String leftHand;
private String rightArm;
private String rightHand;
private String leftFoot;
private String leftLeg;
private String rightFoot;
private String rightLeg;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
public String getHead() {
return head;
}
public void setHead(String head) {
this.head = head;
}
public String getLeftArm() {
return leftArm;
}
public void setLeftArm(String leftArm) {
this.leftArm = leftArm;
}
public String getLeftHand() {
return leftHand;
}
public void setLeftHand(String leftHand) {
this.leftHand = leftHand;
}
public String getRightArm() {
return rightArm;
}
public void setRightArm(String rightArm) {
this.rightArm = rightArm;
}
public String getRightHand() {
return rightHand;
}
public void setRightHand(String rightHand) {
this.rightHand = rightHand;
}
public String getLeftFoot() {
return leftFoot;
}
public void setLeftFoot(String leftFoot) {
this.leftFoot = leftFoot;
}
public String getLeftLeg() {
return leftLeg;
}
public void setLeftLeg(String leftLeg) {
this.leftLeg = leftLeg;
}
public String getRightFoot() {
return rightFoot;
}
public void setRightFoot(String rightFoot) {
this.rightFoot = rightFoot;
}
public String getRightLeg() {
return rightLeg;
}
public void setRightLeg(String rightLeg) {
this.rightLeg = rightLeg;
}
}
public interface PersonBuilder {
void createDoppelganger(String name);
void buildBody();
void buildHead();
void buildLeftArm();
void buildLeftHand();
void buildRightArm();
void buildRightHand();
void buildLeftLeg();
void buildLeftFoot();
void buildRightLeg();
void buildRightFoot();
Person getDoppelganger();
}
/*
* 一个很瘦的人
* /
public class ThinBuilder implements PersonBuilder {
private Person person;
@Override
public void createDoppelganger(String name) {
person = new Person(name);
}
@Override
public void buildBody() {
System.out.println("设置" + person.getName() + "的瘦瘦的身体");
person.setBody("瘦瘦的身体");
}
@Override
public void buildHead() {
System.out.println("设置" + person.getName() + "的小小的头");
person.setHead("小小的头");
}
@Override
public void buildLeftArm() {
System.out.println("设置" + person.getName() + "的瘦瘦的左胳膊");
person.setLeftArm("瘦瘦的左胳膊");
}
@Override
public void buildLeftHand() {
System.out.println("设置" + person.getName() + "的瘦瘦的左手");
person.setLeftHand("瘦瘦的左手");
}
@Override
public void buildRightArm() {
System.out.println("设置" + person.getName() + "的瘦瘦的右胳膊");
person.setRightArm("瘦瘦的右胳膊");
}
@Override
public void buildRightHand() {
System.out.println("设置" + person.getName() + "的瘦瘦的右手");
person.setRightHand("瘦瘦的右手");
}
@Override
public void buildLeftLeg() {
System.out.println("设置" + person.getName() + "的瘦瘦的左腿");
person.setLeftLeg("瘦瘦的左腿");
}
@Override
public void buildLeftFoot() {
System.out.println("设置" + person.getName() + "的小小的左脚");
person.setLeftFoot("小小的左脚");
}
@Override
public void buildRightLeg() {
System.out.println("设置" + person.getName() + "的瘦瘦的右腿");
person.setRightLeg("瘦瘦的右腿");
}
@Override
public void buildRightFoot() {
System.out.println("设置" + person.getName() + "的小小的右脚");
person.setRightFoot("小小的右脚");
}
@Override
public Person getPerson() {
try {
return person;
} finally {
person = null;
}
}
}
/*
* 一个很胖的人
* /
public class FatBuilder implements PersonBuilder {
private Person person;
@Override
public void createDoppelganger(String name) {
person = new Person(name);
}
@Override
public void buildBody() {
System.out.println("设置" + person.getName() + "的胖胖的身体");
person.setBody("胖胖的身体");
}
@Override
public void buildHead() {
System.out.println("设置" + person.getName() + "的大大的头");
person.setHead("大大的头");
}
@Override
public void buildLeftArm() {
System.out.println("设置" + person.getName() + "的胖胖的左胳膊");
person.setLeftArm("胖胖的左胳膊");
}
@Override
public void buildLeftHand() {
System.out.println("设置" + person.getName() + "的胖胖的左手");
person.setLeftHand("胖胖的左手");
}
@Override
public void buildRightArm() {
System.out.println("设置" + person.getName() + "的胖胖的右胳膊");
person.setRightArm("胖胖的右胳膊");
}
@Override
public void buildRightHand() {
System.out.println("设置" + person.getName() + "的胖胖的右手");
person.setRightHand("胖胖的右手");
}
@Override
public void buildLeftLeg() {
System.out.println("设置" + person.getName() + "的胖胖的左腿");
person.setLeftLeg("胖胖的左腿");
}
@Override
public void buildLeftFoot() {
System.out.println("设置" + person.getName() + "的大大的左脚");
person.setLeftFoot("大大的左脚");
}
@Override
public void buildRightLeg() {
System.out.println("设置" + person.getName() + "的胖胖的右腿");
person.setRightLeg("胖胖的右腿");
}
@Override
public void buildRightFoot() {
System.out.println("设置" + person.getName() + "的大大的右脚");
person.setRightFoot("大大的右脚");
}
@Override
public Person getPerson() {
try {
return person;
} finally {
person = null;
}
}
}
/*
* 指挥者
* /
public class PersonDirector {
public Person createDoppelganger(PersonBuilder builder, String name) {
builder.createDoppelganger(name);
builder.buildBody();
builder.buildHead();
builder.buildLeftArm();
builder.buildLeftHand();
builder.buildRightArm();
builder.buildRightHand();
builder.buildLeftLeg();
builder.buildLeftFoot();
builder.buildRightLeg();
builder.buildRightFoot();
return builder.getDoppelganger();
}
}
客户端实现
public class Client {
public static void main(String[] args) {
PersonDirector personDirector = new PersonDirector();
// 制造一个瘦瘦的人
System.out.println("获得了" + personDirector.createDoppelganger(new ThinBuilder(), "person1"));
System.out.println("----------------------------------------");
// 制造一个胖胖的人
System.out.println("获得了" + personDirector.createDoppelganger(new FatBuilder(), "person2"));
}
}
设置person1的瘦瘦的身体
设置person1的小小的头
设置person1的瘦瘦的左胳膊
设置person1的瘦瘦的左手
设置person1的瘦瘦的右胳膊
设置person1的瘦瘦的右手
设置person1的瘦瘦的左腿
设置person1的小小的左脚
设置person1的瘦瘦的右腿
设置person1的小小的右脚
获得了com.feil.design.patterns.builder.Person@74a14482
----------------------------------------
设置person2的胖胖的身体
设置person2的大大的头
设置person2的胖胖的左胳膊
设置person2的胖胖的左手
设置person2的胖胖的右胳膊
设置person2的胖胖的右手
设置person2的胖胖的左腿
设置person2的大大的左脚
设置person2的胖胖的右腿
设置person2的大大的右脚
获得了com.feil.design.patterns.builder.Person@1540e19d
什么时候使用?
- 当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。
- 当构造过程必须允许被构造的对象有不同表示时。
优点
- 具体建造类之间独立,扩展性好。
- 基于 Builder 定义的创建流程一步步构建对象出现错误的概率小。
缺点
产生多余的Build对象以及Dirextor类。