23種設計模式之建造者模式

  • 2019 年 10 月 4 日
  • 筆記

1

/ 寫在前面的話 /

首先,我先舉幾個生活的場景來描述一下建造者模式。比如一個手機,它是有許多複雜的零件組成,當我們組裝這些零件的時候是不是會有一個步驟問題?在實際的開發中,我們所需要的對象構建時,也是非常的複雜,有很多的步驟需要我們去處理。

我們再來說說建造模式的本質:

– 分離了對象子組件的單獨構造(由Builder來負責)和裝配(由Director負責)。 從而可以構造出複雜的對象。這個模式適用於:某個對象的構建過程複雜的情況下使用。

– 由於實現了構建和裝配的解耦。不同的構建器,相同的裝配,也可以做出不同的對象;相同的構建器,不同的裝配順序也可以做出不同的對象。也就是實現了構建算法、裝配算法的解耦,實現了更好的復用。

2

/建造者模式/

  1. 首先我們來模擬一台車輛的建造,我就拿車的引擎和輪胎來說說吧!我們先創建三個類分別是Car , Engine, Tyre 。為了防止創建太多的文件,我就直接寫在一個java文件中。
package com.kuls.builder;    public class Car {     private Tyre tyre;     private Engine engine;       public void lanch(){           System.out.println("出發!!!");       }      public Tyre getTyre() {          return tyre;      }        public void setTyre(Tyre tyre) {          this.tyre = tyre;      }        public Engine getEngine() {          return engine;      }        public void setEngine(Engine engine) {          this.engine = engine;      }  }    /***   * 輪胎   */  class Tyre{      public Tyre() {      }        public Tyre(String name) {          this.name = name;      }        private String name;        public String getName() {          return name;      }        public void setName(String name) {          this.name = name;      }  }    /***   * 引擎   */  class Engine{      public Engine(String name) {          this.name = name;      }        private String name;        public Engine() {        }        public String getName() {          return name;      }        public void setName(String name) {          this.name = name;      }  }

可以看到我們在Car類中定義了Engine和Tyre類,並且提供了set,get方法,我們還寫了一個lanch方法。這裡的get/set方法是為了得到Car對象中的Engine,Tyre。

2.因為我們要將創建車和組裝車兩個步驟分開,我們可以分別定義創建車和組裝車的接口來實現

public interface CarBuilder {      Engine builderEngine();      Tyre builderTyre();  }
public interface CarDirector {      Car directorCar();  }

在CarBuilder接口中我們定義了創建引擎,創建輪胎兩個方法接口,在CarDirector中定義了一個組裝車的接口並且返回值是一個Car對象

我們的物品(輪胎,引擎)和創建者,組裝者都已經弄好了,現在就可以來組裝一台屬於我們的車了,我把這台車命名為ITCar。

3.首先來寫一下 ITCarBuilder

public class ITCarBuilder implements CarBuilder{        @Override      public Engine builderEngine() {          return new Engine("IT資源君版引擎");      }        @Override      public Tyre builderTyre() {          return new Tyre("IT資源君版輪胎");      }  }

可以看到我們是繼承了CarBuilder的接口,這就是我們為啥要去寫CarBuilder接口。然後我們重寫接口中的方法,此時就可以自定義我們的引擎和輪胎了

4.輪胎和引擎創建好後,然後就是來組裝一下我們的車了

public class ITCarDirector implements CarDirector {      private ITCarBuilder itCarBuilder;        public ITCarDirector(ITCarBuilder itCarBuilder) {          this.itCarBuilder = itCarBuilder;      }        @Override      public Car directorCar() {         Engine e = itCarBuilder.builderEngine();         Tyre t =itCarBuilder.builderTyre();         Car car = new Car();         car.setEngine(e);         car.setTyre(t);          return car;      }  }

我們首先創建一個帶參構造器,參數是一個ITCarBuilder對象,傳入這個參數就是要把創建好的引擎和輪胎傳入組裝間進行組裝。在directorCar方法中,我們通過itCarBuilder對象來創建引擎和輪胎,然後創建一個Car對象,並把創建好的引擎和輪胎安裝在這輛車中,然後把這輛車返回。

5.萬事俱備,只欠調用了

public class Test {      public static void main(String[] args){        ITCarDirector itCarDirector = new ITCarDirector(new ITCarBuilder());        Car car = itCarDirector.directorCar();          System.out.println(car.getEngine().getName());          System.out.println(car.getTyre().getName());          car.lanch();      }  }

運行結果:

IT資源君版引擎  IT資源君版輪胎  出發!!!

可以看到我們將建造者和組裝者分離之後創建出的IT版Car

3

/ end /

在我們實際開發中,其實碰到了許多的建造者模式,比如:

– StringBuilder類的append方法

– SQL中的PreparedStatement

– JDOM中,DomBuilder、SAXBuild

若有錯誤,請在後台留言!