一、引子
前幾天陪朋友去裝機店攢了一台電腦,看著裝機工在那裡熟練的裝配著機器,不禁想起來了培訓時講到的建造模式。作為裝機工,他們不用管你用的CPU是Intel還是AMD,也不管你的顯卡是2000千大元還是白送的,都能攣宄淖芭湓谝黃稹惶≒C就誕生了!當然對於客戶來說,你也不知道太多關於PC組裝的細節。這和建造模式是多麼的相像啊!
今天就來探討一下建造模式
二、定義與結構
GOF給建造模式的定義為:將一個復雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。可以將建造模式的精髓概括為:將構造復雜對象的過程和對象的部件解耦。這是對降低耦合、提高可復用性精神的一種貫徹。其實這種精神貫徹在GOF幾乎所有的設計模式中。
是不是和上面提到的裝機流程相像?
這個很多人認為同抽象工廠模式相似的建造模式用在什麼樣的設計環境下呢(對於兩者的比較稍候討論)?我認為可以總結為以下環境:當要生成的產品有復雜的內部結構,其中的內部結構由多個對象組成;系統將來可能要改變產品對象的內部結構的構成或者實現方式,比如說產品的一些屬性現在是從數據庫中得到的,而將來可能從XML中解析得到;而且不能將產品的內部構造完全暴露給客戶程序,一是為了可用性,二是為了安全等因素。滿足上面的設計環境就可以考慮使用建造模式來搭建框架了。 來看看建造模式的組成吧。
抽象建造者角色:這個角色用來規范產品對象的各個組成成分的建造。一般而言,此角色獨立於應用程序的商業邏輯。
具體建造者角色:擔任這個角色的是於應用程序緊密相關的類,它們在指導者的調用下創建產品實例。這個角色在實現抽象建造者角色提供的方法的前提下,達到完成產品組裝,提供成品的功能。
指導者角色:調用具體建造者角色以創建產品對象。指導者並沒有產品類的具體知識,真正擁有產品類的具體知識的是具體建造者對象。 產品角色:建造中的復雜對象。它要包含那些定義組件的類,包括將這些組件裝配成產品的接口。
首先客戶程序創建一個指導者對象,一個建造者角色,並將建造者角色傳入指導者對象進行配置。然後,指導者按照步驟調用建造者的方法創建產品。最後客戶程序從建造者或者指導者那裡得到產品。
從建造模式的工作流程來看,建造模式將產品的組裝“外部化”到了建造者角色中來。這是和任何正規的工廠模式不一樣的——產品的創建是在產品類中完成的。
三、實現
實在找不到太好的例子,我認為《java與模式》中發郵件的例子還算可以。這裡我將《Think in Patterns with Java》中的例子放到這裡權且充個門面。媒體可以存在不同的表達形式,比如書籍、雜志和網絡。這個例子表示不同形式的媒體構造的步驟是相似的,所以可以被提取到指導者角色中去。
import java.util.*;
import junit.framework.*;
//不同的媒體形式:
class Media extends ArrayList {}
class Book extends Media {}
class Magazine extends Media {}
class WebSite extends Media {}
// 進而不含不同的媒體組成元素:
class MediaItem {
private String s;
public MediaItem(String s) { this.s = s; }
public String toString() { return s; }
}
class Chapter extends MediaItem {
public Chapter(String s) { super(s); }
}
class Article extends MediaItem {
public Article(String s) { super(s); }
}
class WebItem extends MediaItem {
public WebItem(String s) { super(s); }
}
// 抽象建造者角色,它規范了所有媒體建造的步驟:
class MediaBuilder {
public void buildBase() {}
public void addMediaItem(MediaItem item) {}
public Media getFinishedMedia() { return null; }
}