建造者模式
定義
建造者模式(Builder Pattern
):將一個複雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。建造者模式是一種對象創建型模式。
場景
當一個對象的構造過程非常複雜,比如有特別多的屬性,或者構造時有特定的順序,甚至是屬性之間有特殊的依賴關係等,這個時候可以使用構建者模式來創建對象。
假設現在要創建計算機學院各個專業的課程表,每個課程表有七天需要安排,如果單獨創建,無疑是非常麻煩的:要麼用一個龐大的構造函數,要麼聲明對象後一個個set,但這兩種方法都不是特別優雅,每個課程表的創建分散無法控制。
UML類圖
代碼
builder
示例:
public class TestBuilder {
@Test
public void test(){
System.out.println(new TimetableDirector(new ComputerScienceTimetableBuilder()).buildTimetable().toString());
System.out.println();
System.out.println(new TimetableDirector(new SoftwareEngineeringTimetableBuilder()).buildTimetable().toString());
/*
Sunday:
Monday: Spoken English
Tuesday: Advanced mathematics
Wednesday: College Physics
Thursday: C Language
Friday: Sports
Saturday: Situation and Policy
Sunday:
Monday: Sports
Tuesday: Discrete Mathematics
Wednesday: College Physics
Thursday: Professional English
Friday: Probability Statistics
Saturday: Situation and Policy
*/
}
}
簡化
這樣子看起來,構建者模式和抽象工廠方法簡直如出一轍,唯一的區別是加了Director
角色處理創建順序,或者處理屬性之間的依賴關,在一定的場景中可以用抽象工廠+模板方法模式來搞定,更多情況下使用的是簡化版本的Builder
模式。
首先可以省略掉Director
類,把構造過程放在各自的Builder
或者放在抽象類中,用模板方法模式來代替:
public abstract class TimetableBuilder {
protected Timetable timetable = new Timetable();
public abstract void sunday();
public abstract void monday();
public abstract void tuesday();
public abstract void wednesday();
public abstract void thursday();
public abstract void friday();
public abstract void saturday();
public Timetable buildTimetable(){
sunday();
monday();
tuesday();
wednesday();
thursday();
friday();
saturday();
return timetable;
}
}
使用時:
public class TestBuilder {
@Test
public void test(){
System.out.println(new ComputerScienceTimetableBuilder().buildTimetable().toString());
System.out.println();
System.out.println(new SoftwareEngineeringTimetableBuilder().buildTimetable().toString());
}
}
在我們並不關注構建過程是否統一,構建類能否統一管理時,抽象類都可以省略,每個類型有自己的構建方法,這也是很多複雜對象的創建方式,詳見:Builgen 插件——IntelliJ IDEA和Eclipse Java Bean Builder模式代碼生成器
這個插件可以自動生成JavaBean的Builder模式代碼,可以採用鏈式調用的方法完成對象的構建,並且可以在build()
方法中檢查依賴,代碼較少,容易理解。
總結
Builder
模式的好處顯而易見:對象的聲明和初始化分離,開發人員不必知道創建的具體過程,但可以通過相同的創建過程來創建不同的對象,對於那些創建複雜的對象是非常有幫助的。
Director
或模板方法模式,可以讓創建過程條理清晰,代碼可讀性更高,這只是針對相似類型的創建,假設類型之間的差別太大,那就不建議使用構建者模式。當類型較多時,可能產生大量的構建者,系統變得特別複雜。
因此在業務場景幾乎不變並且類型構建過程非常相似的場景下,可以使用構建者模式,在其他情況下,如果也想體驗構建者模式帶來的便利,可以使用輕量級的構建者模式,即:Builgen 插件——IntelliJ IDEA和Eclipse Java Bean Builder模式代碼生成器。