意图
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
例子
创建一个狗,非常简单,但是狗里的很多部件都是一个个对象。面对一个复杂的问题,需要复杂的对象来处理。public Class Dog extends Animal {
private String head;
private String limbs;
private String body;
private String tails;
public void setHead(String head) {
this.head = head;
}
public void setLimbs(String limbs) {
this.limbs = limbs;
}
public void setBody(String body) {
this.body = body;
}
public void setTails(String tails) {
this.tails = tails;
}
public void show() {
if (StringUtil.isNotEmpty(head)
&& StringUtil.isNotEmpty(head)
&& StringUtil.isNotEmpty(body)
&& StringUtil.isNotEmpty(tails))
System.out.println("wang!");
}
}
只需要我们填充完毕,小狗就可以表演了。
我们从代码已经看出来他需要哪些组建,但是这个过程并不直接通过new,因为它需要抽象一层,具有广泛性。public interface Builder {
public void buildHead();
public void buildLimbs();
public void buildBody();
public void buildTails();
public Animal build();
}
准备好构建接口后,需要创建一个用于生产小狗的基地。public class DogBuilder implements Builder {
private Dog dog;
public DogBuilder() {
dog = new Dog();
}
public void buildHead() {
dog.setHead("head");
}
public void buildLimbs() {
dog.setLimbs("limbs");
}
public void buildBody() {
dog.setBody("body");
}
public void buildTails() {
dog.setTails("tails");
}
public Animal build() {
return dog;
}
}
这样我们就可以根据构建的DogBuilder来构造小狗了。
接下来,需要让谁来构建小狗:public class World {
private Builder builder;
public World(Builder builder) {
this.builder = builder;
}
public void setBuilder(Builder builder) {
this.builder = builder;
}
public Builder create() {
builder.buildHead();
builder.buildLimbs();
builder.buildBody();
builder.buildTails();
return builder;
}
}
他来帮助我们完成构建一个小狗,并且在此基础上进行抽象为Builder即可。只需要针对指定的Builder实现类添加即可,他会返回给我们需要的对象。public class Garden {
public static void main(String[] arg) {
Builder dog = new DogBuilder();
Builder cat = new CatBuilder();
World world = new World(dog);
Builder dog = world.create();
world.setBuilder(cat);
Builder cat = world.create();
}
}
适用性
- 当创建复杂对象的算法应该独立于该对象的组成部分以及他们的装配方式时。
- 当构造过程必须允许被构造的对象有不同的表示时。
结构
协作
- 客户创建Director对象,并用它所想要的Builder对象进行配置。
- 一旦产品部件被生成,导向器就会通知生成器。
- 生成器处理导向器的请求,并将部件添加到该产品中。
- 客户从生成器中检索产品。
效果
- 它使你可以改变一个产品的内部表示Builder对象提供给导向器一个构造产品的抽象接口。该接口使得生成器可以隐藏这个产品的表示和内部结构。它同时也隐藏了该产品是如何装配的。
- 它将构造代码和表示代码分开Builder模式通过封装一个复杂对象的创建和表示方式提高了对象的模块性。客户不需要知道定义产品内部结构的类的所有信息;这些类是不出现在Builder接口中的。每个ConcreteBuilder包含了创建和装配一个特定产品的所有代码。这些代码只需要写一次;然后不同的Director可以复用它以在相同部件集合的基础上构作不同的Product。
- 它使你可对构造过程进行更精细的控制Builder模式与一下子就生成产品的创建型模式不同,它是在导向者的控制下一步一步构造产品的。仅当该产品完成时导向者才从生成器中取回它。因此Builder接口相比其他创建型模式能更好的反映产品的构造过程。这使你可以更精细的控制构建过程,从而能更精细的控制所得产品的内部结构。