1. 程式人生 > >設計模式(4)-建造者模式

設計模式(4)-建造者模式

簡介

為什麼要使用建造者模式
在軟體開發中,有時會面臨一個建立複雜物件的問題。這個複雜物件的成員很複雜,建立過程也很複雜。這時,就需要使用建造者模式將這個複雜物件的構建分離到一個稱謂建造者的物件裡。即由這個建造者來建立並返回一個完整的複雜物件。

什麼是建造者模式
建造者模式(Builder Pattern,BP):將一個複雜物件的構建與它的表示分離,使得同樣的構建過程可以建立不同的表示。

型別
物件建立型模式

遵守的原則
符合“開閉原則”。指揮者類針對抽象建造者類程式設計,增加新的具體建造者無須修改原有類庫的程式碼,系統擴充套件方便。

角色

  • Product:產品角色,被構建的複雜物件。
  • Builder:抽象建造者。可以是抽象類或者介面。為建立Product物件的各個part提供抽象方法。 在其中一般宣告兩類方法:1、buildPartX(),用於建立Product物件的某個part;2、getResult(),裝配part,用於返回一個完整的Product物件。
  • ConcreteBuilder:具體建造者,實現了或繼承了Builder的類。實現buildPartX(),用於建立Product物件的某個part;實現getResult(),裝配part,用於返回一個完整的Product物件。
  • Director:指揮者,負責複雜物件各個part的建造次序。與Builder之間存在關聯關係,呼叫Builder方法完成複雜物件的建造。一般客戶端只需要與Director互動。

UML類圖
MarkdownPhotos/blob/master/CSDNBlogs/DesignPatterns/builder.png?raw=true

簡化
如果只有一個具體建造者,那麼抽象建造者和指揮者都可以省略。

實現

  • 建立Product類
  • 建立Builder介面
  • 建立兩個構建方式:ConcreteBuilder類和ConcreteBuilder2
  • 建立Director類

Product.java

class Product  {
    private  String partA;
    private  String partB;
    private  String partC;
    //省略Getter和Setter方法、toString()方法
}

Builder.java

public
interface Builder { public void buildPartA(); public void buildPartB(); public void buildPartC(); public Product getResult(); }

ConcreteBuilder.java

public class ConcreteBuilder implements Builder{
    Product product = new Product();

    @Override
    public void buildPartA() {
        product.setPartA("A");      
    }

    @Override
    public void buildPartB() {
        product.setPartB("B");      
    }

    @Override
    public void buildPartC() {
        product.setPartC("C");  
    }

    @Override
    public Product getResult() {
        return product; 
    }
}

ConcreteBuilder2.java

public class ConcreteBuilder2 implements Builder{
    Product product = new Product();

    @Override
    public void buildPartA() {
        product.setPartA("aa");     
    }

    @Override
    public void buildPartB() {
        product.setPartB("bb");     
    }

    @Override
    public void buildPartC() {
        product.setPartC("cc"); 
    }

    @Override
    public Product getResult() {
        return product; 
    }
}

Director.java

public class Director {
    private Builder builder;

    public Director(Builder builder) {
        this.builder = builder;
    }

    public void setBuilder(Builder builder) {
        this.builder = builder;
    }

    public Product construct() {
        builder.buildPartA();
        builder.buildPartB();
        builder.buildPartC();
        return builder.getResult();
    }
}

測試類
BuilderPatternTest.java

public class BuilderPatternTest {
    public static void main(String[] args) {
        ConcreteBuilder concreteBuilder= new ConcreteBuilder();
        Director director = new Director(concreteBuilder);
        Product product = director.construct();
        System.out.println(product.toString());

        ConcreteBuilder2 concreteBuilder2 = new ConcreteBuilder2();
        director = new Director(concreteBuilder2);
        product = director.construct();
        System.out.println(product.toString());
    }
}

測試結果

Product [partA=A, partB=B, partC=C]
Product [partA=aa, partB=bb, partC=cc]

在客戶端程式碼中,無須關心產品物件的具體組裝過程,只需確定具體建造者的型別即可,建造者模式將複雜物件的構建與物件的表現分離開來,這樣使得同樣的構建過程可以創建出不同的表現。

優缺點

優點

  • 低耦合。在建造者模式中, 客戶端不必知道產品內部組成的細節,將產品本身與產品的建立過程解耦。每一個具體建造者都相對獨立,而與其他的具體建造者無關,因此可以很方便地替換具體建造者或增加新的具體建造者, 使用者使用不同的具體建造者即可得到不同的產品物件 。
  • 符合“開閉原則”。指揮者類針對抽象建造者類程式設計,增加新的具體建造者無須修改原有類庫的程式碼,系統擴充套件方便。

缺點
使用範圍有限。如果產品之間的差異性很大,則不適合使用建造者模式,因此其使用範圍受到一定的限制。

適用環境

產品結構複雜,建立物件過程複雜

使用場景
遊戲角色。

問題

建造者模式和抽象工廠模式的比較
返回的產品個數不同。建造者模式只能返回一個複雜產品;而抽象工廠模式可以返回很多產品。

在軟體開發中,你在哪裡用到了建造者模式?
面試的時候經常被問到,好好想想吧^^