将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示.
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); } } ///:~
|