大話設計模式筆記(十)の建造者模式

舉個栗子

問題描述

畫一個小人,有頭、身體、兩手、兩腳就能夠了。算法

簡單實現

人類

/**
 * 人類
 * Created by callmeDevil on 2019/7/21.
 */
public class Person {

    public void drawHead() {
        System.out.print("頭 ");
    }

    public void drawBody() {
        System.out.print("身體 ");
    }

    public void drawHand() {
        System.out.print("兩手 ");
    }

    public void drawLeg() {
        System.out.print("兩腳 ");
    }

}

測試

public class Test {

    public static void main(String[] args) {
        Person person = new Person();
        person.drawHead();
        person.drawBody();
        person.drawHand();
        person.drawLeg();
    }

}

測試結果

頭 身體 兩手 兩腳

存在問題

畫人的時候,頭身手腳是必不可少的,無論什麼人物,開發時是不能少的。但上面測試代碼中時各部分堆積起來,很容易漏寫,好比致使健全的人物卻少了一條「腿」。並且若是須要在別的地方用這些畫小人的程序怎麼辦?編程

簡單實現2

瘦人類

/**
 * 瘦人類
 * Created by callmeDevil on 2019/7/21.
 */
public class PersonThinBuilder {

    private Person person;

    public PersonThinBuilder(Person person){
        this.person = person;
        System.out.println("瘦人類:");
    }

    // 建造瘦子
    public void build(){
        person.drawHead();
        person.drawBody();
        person.drawHand();
        person.drawLeg();
    }

}

胖人類

/**
 * 胖人類
 * Created by callmeDevil on 2019/7/21.
 */
public class PersonFatBuilder {
    // 代碼與瘦人類相似
}

測試

public class Test2 {

    public static void main(String[] args) {
        Person person = new Person();

        PersonThinBuilder thin = new PersonThinBuilder(person);
        thin.build();

        System.out.println();
        PersonFatBuilder fat = new PersonFatBuilder(person);
        fat.build();
    }

}

測試結果

瘦人類:
頭 身體 兩手 兩腳 
胖人類:
頭 身體 兩手 兩腳

存在問題

這樣寫的確達到了能夠複用這兩個畫小人的目的,但容易「缺胳膊少腿」的問題,依然沒有解決,好比如今須要加一個高個的小人,一樣會由於編程不注意,產生一樣問題。ide

建造者模式

定義

將一個複雜對象的構建與它的表示分離,使得一樣的構建過程能夠建立不一樣的表示。 若是使用建造者模式,那麼用戶就只需指定須要建造的類型就能夠獲得它們,而具體建造的過程和細節就不須要知道了。測試

UML圖

代碼實現

建造人抽象類

/**
 * 建造人抽象類
 * Created by callmeDevil on 2019/7/21.
 */
public abstract class PersonBuilder {

    protected Person person;

    public PersonBuilder(Person person){
        this.person = person;
    }

    public abstract void buildHead();
    public abstract void buildBody();
    public abstract void buildArmLeft();
    public abstract void buildArmRight();
    public abstract void buildLegLeft();
    public abstract void buildLegRight();

}

瘦人類2

/**
 * 瘦人類2
 * Created by callmeDevil on 2019/7/21.
 */
public class PersonThinBuilder extends PersonBuilder {

    public PersonThinBuilder(Person person){
        super(person);
    }

    @Override
    public void buildHead() {
        System.out.print("頭 ");
    }

    @Override
    public void buildBody() {
        System.out.print("身體 ");
    }

    @Override
    public void buildArmLeft() {
        System.out.print("左手 ");
    }

    @Override
    public void buildArmRight() {
        System.out.print("右手 ");
    }

    @Override
    public void buildLegLeft() {
        System.out.print("左腳 ");
    }

    @Override
    public void buildLegRight() {
        System.out.print("右腳 ");
    }

}

胖人類2

/**
 * 胖人類2
 * Created by callmeDevil on 2019/7/21.
 */
public class PersonFatBuilder extends PersonBuilder{
    // 代碼與瘦人類2相似
}

建造人指揮者

/**
 * 建造人指揮者
 * Created by callmeDevil on 2019/7/21.
 */
public class PersonDirector {
    
    private PersonBuilder builder;
    
    public PersonDirector(PersonBuilder builder){
        // 用戶告訴指揮者須要什麼樣的小人
        this.builder = builder;
    }
    
    // 根據用戶的選擇建造小人
    public void createPerson(){
        builder.buildHead();
        builder.buildBody();
        builder.buildArmLeft();
        builder.buildArmRight();
        builder.buildLegLeft();
        builder.buildLegRight();
    }
    
}

測試

public class Test {

    public static void main(String[] args) {
        Person person = new Person();
        PersonDirector thinDirector = new PersonDirector(new PersonThinBuilder(person));
        thinDirector.createPerson();

        System.out.println();
        PersonDirector fatDirector = new PersonDirector(new PersonFatBuilder(person));
        fatDirector.createPerson();
    }

}

測試結果

瘦人類2:
頭 身體 左手 右手 左腳 右腳 
胖人類2:
頭 身體 左手 右手 左腳 右腳

此時若是須要增長一個高個子和矮個子的小人,應該怎麼作?
加兩個類,一個高個子類和一個矮個子類,都繼承 PersonBuilder ,而後客戶端調用便可。ui

總結

  • 主要是用於建立一些複雜的對象,這些對象內部構建間的建造順序一般是穩定的,但對象內部的構建一般面臨着複雜的變化
  • 建造者模式的好處就是使得建造代碼與表示代碼分離,因爲建造者隱藏了該產品是如何組裝的,因此若須要改變一個產品的內部表示,只須要再定義一個具體的建造者就能夠了
  • 建造者模式是在當建立複雜對象的算法應該獨立於該對象的組成部分以及它們的裝配方式時適用的模式
相關文章
相關標籤/搜索