思路:多態下,建造不同類型的“建築”,通過第三方監工監製,用戶調用監工即可
場景之一:蓋房子舉例,房子本身有很多個組成部分,各組件息息相關缺一不可,否則房倒屋塌。而其構造過程也是相當複雜的,但大家不必擔心,爲響應我們簡約直觀的一貫宗旨,這裏只將其簡化拆分成地基、牆體、屋頂三部分,首先來看建築物類。
package com.yitian.builder;
import java.util.ArrayList;
import java.util.List;
/**
* @Description 建築物
* @Author yitianRen
* @Date 2019/9/17 10:34
* @Version 1.0
**/
public class Building {
// 用來模擬房子組件的堆疊
private List<String> buildingComponents = new ArrayList<>();
public void setBasement(String basement) {// 地基
this.buildingComponents.add(basement);
}
public void setWall(String wall) {// 牆體
this.buildingComponents.add(wall);
}
public void setRoof(String roof) {// 房頂
this.buildingComponents.add(roof);
}
@Override
public String toString() {
String buildingStr = "";
for (int i = buildingComponents.size() - 1; i >= 0; i--) {
buildingStr += buildingComponents.get(i);
}
return buildingStr;
}
}
爲了模擬建築物通用類中各組件的建造順序,我們在第以List來模擬三個組件的堆疊,之後是它們對應的三個建造方法,最後於的toString方法自下而上的打印出最終完成的房子。看起來是不難,但怎樣從這個類直接構造出一個房子呢?怎樣去設置這些字符串的組件屬性呢?此時客戶端一頭霧水,還是找個專業施工方吧,先定義個施工方接口。
package com.yitian.builder;
/**
* @Author:yitianRen
* @Date:10:37 2019/9/17
* Description:施工者 建造
*/
public interface Builder {
public void buildBasement();
public void buildWall();
public void buildRoof();
public Building getBuilding();
}
別墅施工者:
package com.yitian.builder;
/**
* @Description 建造別墅
* @Author yitianRen
* @Date 2019/9/17 10:39
* @Version 1.0
**/
public class HouseBuilder implements Builder {
private Building house;
public HouseBuilder() {
house = new Building();
}
@Override
public void buildBasement() {
System.out.println("挖地基,部署管道、線纜,水泥加固,搭建圍牆、花園。");
house.setBasement("╬╬╬╬╬╬╬╬\n");
}
@Override
public void buildWall() {
System.out.println("搭建木質框架,石膏板封牆並粉飾內外牆。");
house.setWall("|田|田 田|\n");
}
@Override
public void buildRoof() {
System.out.println("建造木質屋頂、閣樓,安裝煙囪,做好防水。");
house.setRoof("╱◥███◣\n");
}
@Override
public Building getBuilding() {
return house;
}
}
公寓施工者:
package com.yitian.builder;
/**
* @Description 建造八層公寓
* @Author yitianRen
* @Date 2019/9/17 10:42
* @Version 1.0
**/
public class ApartmentBuilder implements Builder {
private Building apartment;
public ApartmentBuilder() {
apartment = new Building();
}
@Override
public void buildBasement() {
System.out.println("深挖地基,修建地下車庫,部署管道、線纜、風道。");
apartment.setBasement("╚═════════╝\n");
}
@Override
public void buildWall() {
System.out.println("搭建多層建築框架,建造電梯井,鋼筋混凝土澆灌。");
for (int i = 0; i < 8; i++) {// 此處假設固定8層
apartment.setWall("║ □ □ □ □ ║\n");
}
}
@Override
public void buildRoof() {
System.out.println("封頂,部署通風井,做防水層,保溫層。");
apartment.setRoof("╔═════════╗\n");
}
@Override
public Building getBuilding() {
return apartment;
}
}
這時候建築有了,施工者有了,那麼需要一個監工負責監製:
package com.yitian.builder;
/**
* @Description 監工
* @Author yitianRen
* @Date 2019/9/17 10:51
* @Version 1.0
**/
public class Director {
private Builder builder;
public Director(Builder builder) {
this.builder = builder;
}
public void setBuilder(Builder builder) {
this.builder = builder;
}
public Building direct() {
System.out.println("=====工程項目啓動=====");
// 第一步,打好地基;
builder.buildBasement();
// 第二步,建造框架、牆體;
builder.buildWall();
// 第三步,封頂;
builder.buildRoof();
System.out.println("=====工程項目竣工=====");
return builder.getBuilding();
}
}
一切都有了,客戶這下可以方便的請大家爲自己建造房子了,別墅和八層小公寓要建造了!
package com.yitian.builder;
/**
* @Description 客戶尋求監工監製住房
* @Author yitianRen
* @Date 2019/9/17 10:53
* @Version 1.0
**/
public class Client {
public static void main(String[] args) {
//招工,建別墅。
Builder builder = new HouseBuilder();
//交給工程總監
Director director = new Director(builder);
System.out.println(director.direct());
//替換施工方,建公寓。
director.setBuilder(new ApartmentBuilder());
System.out.println(director.direct());
/*
=====工程項目啓動=====
挖地基,部署管道、線纜,水泥加固,搭建圍牆、花園。
搭建木質框架,石膏板封牆並粉飾內外牆。
建造木質屋頂、閣樓,安裝煙囪,做好防水。
=====工程項目竣工=====
╱◥███◣
|田|田 田|
╬╬╬╬╬╬╬╬
=====工程項目啓動=====
深挖地基,修建地下車庫,部署管道、線纜、風道。
搭建多層建築框架,建造電梯井,鋼筋混凝土澆灌。
封頂,部署通風井,做防水層,保溫層。
=====工程項目竣工=====
╔═════════╗
║ □ □ □ □ ║
║ □ □ □ □ ║
║ □ □ □ □ ║
║ □ □ □ □ ║
║ □ □ □ □ ║
║ □ □ □ □ ║
║ □ □ □ □ ║
║ □ □ □ □ ║
╚═════════╝
*/
}
}
項目終於竣工了,對於複雜對象的構建,專業的建造團隊顯然是不可或缺的,尤其是產品內部組件間有某種關聯性,構建的順序性,所以我們把製造工序抽離出來交給了工程總監(Director),而產品各種製造工藝則被多態化交給不同的施工方(Builder)去各顯神通,最終達成以相同的構造過程生產不同產品的展現的目的,工序不可亂,工藝不可缺
文章來源 微信公衆號 java知音 設計模式