建造者模式:將一個複雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。
建造者模式其實就是使用多個簡單對象一步步的創建一個複雜對象。用戶只需要給出指定複雜對象的類型和內容,建造者模式負責按順序創建複雜對象(把內部的建造過程和細節隱藏起來)。
建造者模式符合依賴倒置原則:
- 高層次的模塊不應該依賴於低層次的模塊,他們都應該依賴於抽象。
- 抽象不應該依賴於具體實現,具體實現應該依賴於抽象。
建造者模式UML類圖:
- Builder:給出一個抽象接口,以規範產品對象的各個組成成分的建造。這個接口規定要實現複雜對象的哪些部分的創建,並不涉及具體的對象部件的創建。
- ConcreteBuilder:實現Builder接口,針對不同的商業邏輯,具體化複雜對象的各部分的創建。 在建造過程完成後,提供產品的實例。
- Director:聚合關聯Builder,調用具體建造者來創建複雜對象的各個部分,在指導者中不涉及具體產品的信息,只負責保證對象各部分完整創建或按某種順序創建。
- Product:要創建的複雜對象。
建造者模式代碼:
//Director接口
interface AirShipDirector {
//組裝船對象
AirShip directAirShip();
}
//Builder接口
interface AirShipBuilder {
Engine builderEngine();
OrbitalModule builderOrbitalModule();
EscapeTower builderEscapeTower();
}
//Builder實現類
class SxtAirShipBuilder implements AirShipBuilder {
@Override
public Engine builderEngine() {
System.out.println("構建飛天發動機!");
return new Engine("飛天發動機!");
}
@Override
public EscapeTower builderEscapeTower() {
System.out.println("構建逃逸塔");
return new EscapeTower("飛天逃逸塔");
}
@Override
public OrbitalModule builderOrbitalModule() {
System.out.println("構建軌道艙");
return new OrbitalModule("飛天軌道艙");
}
}
//Director實現類
class SxtAirshipDirector implements AirShipDirector {
private AirShipBuilder builder;
public SxtAirshipDirector(AirShipBuilder builder) {
this.builder = builder;
}
@Override
public AirShip directAirShip() {
Engine e = builder.builderEngine();
OrbitalModule o = builder.builderOrbitalModule();
EscapeTower et = builder.builderEscapeTower();
//裝配成飛船對象
AirShip ship = new AirShip();
ship.setEngine(e);
ship.setEscapeTower(et);
ship.setOrbitalModule(o);
return ship;
}
}
//實體類
class AirShip {
private OrbitalModule orbitalModule; //軌道艙
private Engine engine; //發動機
private EscapeTower escapeTower; //逃逸塔
public OrbitalModule getOrbitalModule() {
return orbitalModule;
}
public void setOrbitalModule(OrbitalModule orbitalModule) {
this.orbitalModule = orbitalModule;
}
public Engine getEngine() {
return engine;
}
public void setEngine(Engine engine) {
this.engine = engine;
}
public EscapeTower getEscapeTower() {
return escapeTower;
}
public void setEscapeTower(EscapeTower escapeTower) {
this.escapeTower = escapeTower;
}
@Override
public String toString() {
return "AirShip{" +
"orbitalModule=" + orbitalModule +
", engine=" + engine +
", escapeTower=" + escapeTower +
'}';
}
}
//軌道艙對象
class OrbitalModule{
private String name;
public OrbitalModule(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "OrbitalModule{" +
"name='" + name + '\'' +
'}';
}
}
//發動機對象
class Engine {
private String name;
public Engine(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Engine{" +
"name='" + name + '\'' +
'}';
}
}
//逃逸塔對象
class EscapeTower{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public EscapeTower(String name) {
super();
this.name = name;
}
@Override
public String toString() {
return "EscapeTower{" +
"name='" + name + '\'' +
'}';
}
}
public class ShipBuilder {
public static void main(String[] args) {
AirShipDirector director = new SxtAirshipDirector(new SxtAirShipBuilder());
AirShip ship = director.directAirShip();
System.out.println(ship);
}
}
運行結果:
- 構建飛天發動機!
- 構建軌道艙
- 構建逃逸塔
- AirShip{orbitalModule=OrbitalModule{name='飛天軌道艙'}, engine=Engine{name='飛天發動機!'}, escapeTower=EscapeTower{name='飛天逃逸塔'}}
建造者模式優點:
- 易於解耦 :將產品本身與產品創建過程進行解耦,可以使用相同的創建過程來得到不同的產品。也就說細節依賴抽象。
- 易於精確把控對象的創建 :將複雜產品的創建步驟分解在不同的方法中,使得創建過程更加清晰
- 易於拓展 :增加新的具體建造者無需修改原有類庫的代碼,易於拓展,符合“開閉原則“。
建造者模式缺點:
- 建造者模式所創建的產品一般具有較多的共同點,其組成部分相似;如果產品之間的差異性很大,則不適合使用建造者模式,因此其使用範圍受到一定的限制。
- 如果產品的內部變化複雜,可能會導致需要定義很多具體建造者類來實現這種變化,導致系統變得很龐大
當生成的類比較複雜,並且生成的內部對象又相互依賴關係的情況下,可以選擇建造者模式。