一、小案例分析 1、功能需求: 現需要建房子,建房流程:挖地基、砌牆、封頂。對於不同種類的房子(高樓,別墅),流程雖然一樣,但是具體功能實現不同。如何實現建房子? 2、小菜雞的答案: (1)定義一個抽象介面,並定義三個抽象方法(挖地基、砌牆、封頂)。(2)對於不同種類的房子,實現該介面,並重寫相關方 ...
一、小案例分析
1、功能需求:
現需要建房子,建房流程:挖地基、砌牆、封頂。對於不同種類的房子(高樓,別墅),流程雖然一樣,但是具體功能實現不同。如何實現建房子?
2、小菜雞的答案:
(1)定義一個抽象介面,並定義三個抽象方法(挖地基、砌牆、封頂)。
(2)對於不同種類的房子,實現該介面,並重寫相關方法即可。
(3)代碼實現:
package builder.pattern; /** * 測試類 * */ public class BuilderDemo { public static void main(String[] args) { System.out.println("建別墅流程:"); BuilderHouse villa = new Villa(); System.out.println("\n建高樓流程"); BuilderHouse highBuild = new HighBuild(); } } /** * 定義一個建房子的介面,並定義其流程 */ interface BuilderHouse { void scoopHole(); // 挖地基 void buildWall(); // 砌牆 void topOff(); // 封頂 } /** * 建別墅,實現建房子的介面 * */ class Villa implements BuilderHouse { /** * 建別墅流程 */ public Villa() { scoopHole(); buildWall(); topOff(); } @Override public void scoopHole() { System.out.println("挖10米地基"); } @Override public void buildWall() { System.out.println("砌10層牆"); } @Override public void topOff() { System.out.println("樓頂建個游泳池"); } } /** * 建高樓流程,實現建房子的介面 * */ class HighBuild implements BuilderHouse { /** * 建高樓流程 */ public HighBuild() { scoopHole(); buildWall(); topOff(); } @Override public void scoopHole() { System.out.println("挖30米地基"); } @Override public void buildWall() { System.out.println("砌60層牆"); } @Override public void topOff() { System.out.println("樓頂建個停機坪"); } }
(4)代碼分析:
容易理解並操作,但是程式的擴展性不好,且耦合性強(將產品與創建產品的過程封裝在一起)。
(5)UML圖
二、建造者模式
1、什麼是建造者模式
又叫生成器模式,其將複雜的對象的建造過程抽象出來,併在其子類中去實現不同的建造。用戶只需要去調用就行,不需要管建造的內部細節如何實現。簡單的理解為,將一堆零件拼成一個整體,而零件是抽象的,並由不同的子類去實現,用戶不需要管零件是如何形成的,能組裝就行。
2、建造者模式的核心角色
(1)產品(Product):一個具體的產品對象。
(2)抽象建造者(Builder):定義一個介面或抽象類,內部定義生成產品各個零件的抽象方法。
(3)具體建造者(ConcreateBuilder):實現介面,並重寫生成各零件的方法。
(4)組裝者(Commander):按照流程拼接零件,並返回一個對象。
(5)代碼實現:
package builder.pattern; /** * 測試類 * */ public class BuilderDemo { public static void main(String[] args) { System.out.println("建別墅流程:"); HouseBuilder villaBuilder = new VillaBuilder(); HouseCommandar villaCommandar = new HouseCommandar(villaBuilder); System.out.println(villaCommandar.createHouse()); System.out.println("\n建高樓流程"); HouseBuilder highBuildBuilder = new HighBuildBuilder(); HouseCommandar highBuildCommandar = new HouseCommandar(highBuildBuilder); System.out.println(highBuildCommandar.createHouse()); } } /** * 產品類 * */ class House { private String basis; private String wall; private String roof; public String getBasis() { return basis; } public void setBasis(String basis) { this.basis = basis; } public String getWall() { return wall; } public void setWall(String wall) { this.wall = wall; } public String getRoof() { return roof; } public void setRoof(String roof) { this.roof = roof; } @Override public String toString() { return "House [basis=" + basis + ", wall=" + wall + ", roof=" + roof + "]"; } } /** * 抽象建造者,內部定義生成產品各個零件的抽象方法。 * */ abstract class HouseBuilder { House house = new House(); public abstract void scoopHole(); // 挖地基 public abstract void buildWall(); // 砌牆 public abstract void topOff(); // 封頂 public House getHouse() { return house; } } /** * 具體建造者,建別墅,繼承抽象類,並重寫相關方法 * */ class VillaBuilder extends HouseBuilder { @Override public void scoopHole() { house.setBasis("挖10米地基"); } @Override public void buildWall() { house.setWall("砌10層牆"); } @Override public void topOff() { house.setRoof("樓頂建個游泳池"); } } /** * 建高樓流程,實現建房子的介面 * */ class HighBuildBuilder extends HouseBuilder { @Override public void scoopHole() { house.setBasis("挖30米地基"); } @Override public void buildWall() { house.setWall("砌60層牆"); } @Override public void topOff() { house.setRoof("樓頂建個停機坪"); } } /** * 組裝者,控制零件組合流程,並返回一個產品對象 */ class HouseCommandar { private HouseBuilder houseBuilder; /** * 獲取具體的建造者 */ public HouseCommandar(HouseBuilder houseBuilder) { this.houseBuilder = houseBuilder; } /** * 控制建房流程,並返回一個房子實例 * * @return 房子實例 */ public House createHouse() { houseBuilder.scoopHole(); houseBuilder.buildWall(); houseBuilder.topOff(); return houseBuilder.getHouse(); } }
(6)代碼分析:
相比於上例,其將控制產品流程的代碼抽出來了。使產品與產品構建流程分離,從而在一定程度上解耦。當擴展代碼時,只需繼承HouseBuilder 並重寫相關方法即可。
(7)UML圖:
3、抽象工廠模式與建造者模式的區別
(1)抽象工廠模式是根據不同的工廠去創建一個對象。
(2)建造者模式是根據流程去組裝一個對象。
三、JDK源碼分析(StringBuilder)
1、部分源碼
public final class StringBuilder extends AbstractStringBuilder implements java.io.Serializable, CharSequence{ } abstract class AbstractStringBuilder implements Appendable, CharSequence{ //內部定義了一系列方法,且部分方法返回值類型為AbstractStringBuilder public AbstractStringBuilder append(String str) { if (str == null) return appendNull(); int len = str.length(); ensureCapacityInternal(count + len); str.getChars(0, len, value, count); count += len; return this; } public AbstractStringBuilder deleteCharAt(int index) { if ((index < 0) || (index >= count)) throw new StringIndexOutOfBoundsException(index); System.arraycopy(value, index+1, value, index, count-index-1); count--; return this; } }
2、源碼分析
AbstractStringBuilder 內部定義了一系列返回值類型為AbstractStringBuilder 的方法,這些方法可以組合起來,形成鏈式調用(產品構建流程),根據鏈式調用來組裝成最後返回的對象。
即StringBuilder 是組裝者與具體建造者。AbstractStringBuilder 是抽象建造者。