(文章翻译自Java Design Pattern: Builder)
构造器模式的关键之处在于它使用一步接招一步的流程去构建东西,例如:尽管构建的每一步是不相同的但是每一个产品还是遵循相同的流程。
在下面的例子中,我们定义了一个叫做StarbucksBuilder 的饮料的构造器,它可以构造Starbucks饮料。StarbucksBuilder 在构建一个Starbucks饮料的时候有几个步骤,比如buildSize()和buildDrink(),最后返回了构建完成的饮料。
1.构造器模式类图
2.构造器模式设计Java代码例子:
package designpatterns.builder;
// produce to be built
class Starbucks {
private String size;
private String drink;
public void setSize(String size) {
this.size = size;
}
public void setDrink(String drink) {
this.drink = drink;
}
}
//abstract builder
abstract class StarbucksBuilder {
protected Starbucks starbucks;
public Starbucks getStarbucks() {
return starbucks;
}
public void createStarbucks() {
starbucks = new Starbucks();
System.out.println("a drink is created");
}
public abstract void buildSize();
public abstract void buildDrink();
}
// Concrete Builder to build tea
class TeaBuilder extends StarbucksBuilder {
public void buildSize() {
starbucks.setSize("large");
System.out.println("build large size");
}
public void buildDrink() {
starbucks.setDrink("tea");
System.out.println("build tea");
}
}
// Concrete builder to build coffee
class CoffeeBuilder extends StarbucksBuilder {
public void buildSize() {
starbucks.setSize("medium");
System.out.println("build medium size");
}
public void buildDrink() {
starbucks.setDrink("coffee");
System.out.println("build coffee");
}
}
//director to encapsulate the builder
class Waiter {
private StarbucksBuilder starbucksBuilder;
public void setStarbucksBuilder(StarbucksBuilder builder) {
starbucksBuilder = builder;
}
public Starbucks getstarbucksDrink() {
return starbucksBuilder.getStarbucks();
}
public void constructStarbucks() {
starbucksBuilder.createStarbucks();
starbucksBuilder.buildDrink();
starbucksBuilder.buildSize();
}
}
//customer
public class Customer {
public static void main(String[] args) {
Waiter waiter = new Waiter();
StarbucksBuilder coffeeBuilder = new CoffeeBuilder();
//Alternatively you can use tea builder to build a tea
//StarbucksBuilder teaBuilder = new TeaBuilder();
waiter.setStarbucksBuilder(coffeeBuilder);
waiter.constructStarbucks();
//get the drink built
Starbucks drink = waiter.getstarbucksDrink();
}
}
3.构造器模式的实际应用
构造器模式在大量的类库中得到了应用,但是他们犯了一个相同的错误。以下面的来自于Java标准类库中的StringBuilder为例,它真的使用了构造器模式吗??
StringBuilder strBuilder= new StringBuilder();
strBuilder.append("one");
strBuilder.append("two");
strBuilder.append("three");
String str= strBuilder.toString();
在Java标准类库中,StringBuilder 继承了AbstractStringBuilder。
append() 是这个过程的一步,就像我们Starbucks 例子中的一步。toString()方法是另外一步也是最后一步。但是区别的是在图中没有waiter。Waiter在构造器模式中扮演主导的角色。因为它没有这样的角色所以它不是一个构造器模式。
当然了,这不是唯一的原因。你可以比较开始中的那张图并且找出其他的原因。
4.构造器和工程的区别
当有很多步奏去创建一个对象的时候才会用到构造器设计模式。而当工长很容易在一个方法调用的时候就创建了整个对象的时候会用到工长模式。