Builder模式

04-03-27 tbase
    

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示.

Builder的目标是从“ 不同的表示”分离出构建过程。这里,构建过程是必须是相同的,但是产生的结果却有不同的表现。GoF 指出Builder与Abstract Factory主要的不同在于Builder是step-by-step的,因此构建过程应该是分步骤的。另外,进入Builder的内容应该是连续的物件。

这里,我仍然是用汽车装配来举例(Builder),例如,我的工厂需要装配3种汽车,他们是货车,小汽车,和公共汽车。装配的内容是发动机,轮胎和车厢。他们装配的次序如下第一步装配发动机,第二步装配车厢,第三步装配轮胎.因为这里我们有着相同的装配步骤,但是,结果的表现肯定是不同的,因此我们这里只可以使用Builder模式,而不是Abstract Factory。

package builder;

import java.util.*;
import junit.framework.*;

//不同的描述
class Automobile extends ArrayList {}
class Car extends Automobile {}
class Truck extends Automobile {}
class Bus extends Automobile {}

// ... 使用的物品
class PartItem {
  private String s;
  public PartItem(String s) { this.s = s; }
  public String toString() { return s; }
}

class Engine extends PartItem {
  public Engine(String s) { super(s); }
}
class Tyre extends PartItem {
  public Tyre(String s) { super(s); }
}
class Carriage extends PartItem {
  public Carriage(String s) { super(s); }
}

// ...各种步骤
class AutoBuilder {
  public void buildBase() {}
  //装配方法不一样
  public void addAutomobileItem(PartItem item) {}   //step
  //检查方法也不一样
  public void checkAutomobileItem(PartItem item) {} //step
  //都要出去跑两圈
  public void testAutomobile() {}
  public Automobile getFinishedAutomobile() { return null; }
}

class CarBuilder extends AutoBuilder {
  private Car b;
  public void buildBase() {
    System.out.println("Building Car framework");
    b = new Car();
  }
  public void addAutomobileItem(PartItem part) {
    System.out.println("Adding Car part " + part);
    b.add(part);
  }
  public Automobile getFinishedAutomobile() { return b; }
}

class TruckBuilder extends AutoBuilder {
  private Truck m;
  public void buildBase() {
    System.out.println("Building Truck framework");
    m = new Truck();
  }
  public void addAutomobileItem(PartItem part) {
    System.out.println("Adding part " + part);
    m.add(part);
  }
  public Automobile getFinishedAutomobile() { return m; }
}

class BusBuilder extends AutoBuilder {
  private Bus w;
  public void buildBase() {
    System.out.println("Building Bus framework");
    w = new Bus();
  }
  public void addAutomobileItem(PartItem part) {
    System.out.println("Adding part " + part);
    w.add(part);
  }
  public Automobile getFinishedAutomobile() { return w; }
}

class AutomobileDirector { // "Context"
  private AutoBuilder mb;
  public AutomobileDirector(AutoBuilder mb) {
    this.mb = mb; // Strategy-ish
  }

  //这里是step-by-step的,不同于Abstract Factory
  public Automobile produceAuto(List input) {
    mb.buildBase();
    for(Iterator it = input.iterator(); it.hasNext();){
      PartItem p  = (PartItem) it.next();
      mb.addAutomobileItem( p);
      mb.checkAutomobileItem(p);
    }
    mb.testAutomobile();
    return mb.getFinishedAutomobile();
  }
};

public class BuildAutomobile extends TestCase {
  private List input = Arrays.asList(new PartItem[] {
    new Engine("Engine"), new Carriage("Carriage"),
    new Tyre("Tyre")
  });

  public void testCar() {
    AutomobileDirector buildCar =
      new AutomobileDirector(new CarBuilder());
    Automobile car = buildCar.produceAuto(input);
    String result = "Car: " + car;
    System.out.println(result);
    assertEquals(result,
      "Car: [Engine, Carriage, Tyre]");
  }
  public void testTruck() {
    AutomobileDirector buildTruck =
      new AutomobileDirector(new TruckBuilder());
    Automobile truck = buildTruck.produceAuto(input);
    String result = "Truck: " + truck;
    System.out.println(result);
    assertEquals(result,
      "Truck: [Engine, Carriage, Tyre]");
  }
  public void testBus() {
    AutomobileDirector buildBus =
      new AutomobileDirector(new BusBuilder());
    Automobile bus = buildBus.produceAuto(input);
    String result = "Bus: " + bus;
    System.out.println(result);
    assertEquals(result,
      "Bus: [Engine, Carriage, Tyre]");
  }
  public static void main(String[] args) {
    junit.textui.TestRunner.run(BuildAutomobile.class);
  }
} ///:~
<p>

    

xuzhenhua21
2004-03-27 13:58

代码部分太小了,不太好看(没有指责楼主的意思)

补充一句:零件数不同可以,可以是空方法!

辛苦了!