在建造大楼的时候,需要先打牢地基,搭建框架,再自下而上一层层盖,构建这类具有复杂结构的物体时,很难一气呵成。所以我们需要首先建造组成这个物体的各个部分,然后分阶段将它们组装起来。

  1. 首先需要一个Builder类,声明了方法的抽象类。

    1. public abstract class Builder {
    2. public abstract void makeTitle(String title);
    3. public abstract void makeString(String title);
    4. public abstract void makeItems(String[] items);
    5. public abstract void close();
    6. }
  2. 其次需要一个Director来管理所有的类。

    1. public class Director {
    2. private Builder builder;
    3. public Director(Builder builder) {
    4. this.builder = builder;
    5. }
    6. public void construct(){
    7. builder.makeTitle("Greeting");
    8. builder.makeString("从早到晚");
    9. builder.makeItems(new String[]{
    10. "早上好",
    11. "下午好",
    12. });
    13. builder.makeString("晚上");
    14. builder.makeItems(new String[]{
    15. "晚上好",
    16. });
    17. builder.close();
    18. }
    19. }

    其中的construct中使用是抽象方法。

  3. Builder的实现类,将其中的抽象方法具体实现。 ```java public class TextBuilder extends Builder { private StringBuffer buffer = new StringBuffer();

    @Override public void makeTitle(String title) {

    1. buffer.append("===========================\n");
    2. buffer.append("["+title+"]");
    3. buffer.append("\n");

    } @Override public void makeString(String str) {

    1. buffer.append('O'+str+"\n");
    2. buffer.append("\n");

    } @Override public void makeItems(String[] items) {

    1. for (int i = 0; i < items.length; i++) {
    2. buffer.append(" ."+items[i]+"\n");
    3. }
    4. buffer.append("\n");

    } @Override public void close() {

    1. buffer.append("=====================\n");

    } public String getResult(){

    1. return buffer.toString();

    }

} ``` 从代码中可以看出:Builder模型中有多个角色。

  1. Builder(建造者):

负责定义实例中的功能接口。

  1. ConCreteBuilder(具体的建造者):

负责实现Builder角色中的具体接口。

  1. Director(监工):

负责使用建造者的接口,不依赖于ConCreteBuilder,确保无论ConCreteBuilder是怎么定义的,Director都可以正常工作,只调用在Builder中定义的方法。

相关的设计模式:

Template Method:

在Builder模式中,Director角色控制Builder角色。在Template Method模式中,父类控制子类。

Composite模式:

有些情况下Builder模式生成的实例构成了Composite模式。

Abstract Factory模式:

Builder模式和Abstract Factory模式都用于生产复杂的实例。

Facade模式:

在Builder模式中,Director角色通过组合Builder角色中的复杂方法向外部提供可以简单生成实例的接口。
而Facade模式中的Facade角色则是通过组合内部模块向外部提供可以简单调用的接口。

思路:

可替换性:

Direct和Builder的子类并没有关联,Main类中调用的也是Direct而不是Builder,只有不知道子类才能替换。正是因为可以替换,组件才具有高价值。作为设计人员,“可替换性”非常重要。

设计接口时能够决定和不能决定的事情:

在Builder类中,需要声明实现功能所有需要的所有方法。Director类中使用的方法都是Builder中提供的。所以,在Builder中应当定义哪些方法是非常重要的。
而且,Builder类还必须能够应对将来子类可能增加的需求。在将来可能会对Builder建立新的子类,如果需要新的方法的话,之前的子类也要去实现其中的抽象方法。
所以,还是要尽可能让设计的类能够尽可能灵活地应对近期发生的变化。

问题:

如何在调用Builder的某些方法前,必须先调用一次makeTitle方法,且只能调用一次?
需要对Builder类中加入检查调用顺序的方法。使用新的方法来包装之前的接口,然后将之前的接口置为protected即可。