Builder模式

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

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);
}
}
///:~

代码部分太小了,不太好看(没有指责楼主的意思)
补充一句:零件数不同可以,可以是空方法!
辛苦了!