java設(shè)計(jì)模式--建造者模式詳解
引例
需求:建造房子,建造過(guò)程包括打地基、砌墻和封頂。房子各式各樣,包括平房和別墅,編程模擬實(shí)現(xiàn)。
一般解法
思路:定義房子類,包括建房的方法,然后定義平房和別墅繼承房子類,重寫(xiě)相關(guān)方法。
類圖:

代碼:
AbstractHouse(房子)
public abstract class AbstractHouse {
public abstract void buildBasic();//打地基
public abstract void buildWalls();//砌墻
public abstract void buildRoof();//封頂
public void build() { //建房
buildBasic(); //三個(gè)步驟(注意順序)
buildWalls();
buildRoof();
}
}
Bungalow(平房)
public class Bungalow extends AbstractHouse{
@Override
public void buildBasic() {
System.out.println("平房打地基");
}
@Override
public void buildWalls() {
System.out.println("平房砌墻");
}
@Override
public void buildRoof() {
System.out.println("平房封頂");
}
}
Villa (別墅)
public class Villa extends AbstractHouse{
@Override
public void buildBasic() {
System.out.println("別墅打地基");
}
@Override
public void buildWalls() {
System.out.println("別墅砌墻");
}
@Override
public void buildRoof() {
System.out.println("別墅封頂");
}
}
客戶端調(diào)用
public class Client {
public static void main(String[] args) {
Bungalow bungalow = new Bungalow();
bungalow.build();
Villa villa = new Villa();
villa.build();
}
}
運(yùn)行結(jié)果:

缺點(diǎn):
程序不好擴(kuò)展和維護(hù),把產(chǎn)品和創(chuàng)建產(chǎn)品過(guò)程封裝在一起,耦合性高。
解耦產(chǎn)品和創(chuàng)建產(chǎn)品過(guò)程=》建造者模式
建造者模式
建造者模式(Builder Pattern)又叫生成器模式,是一種對(duì)象構(gòu)建模式。它可以將復(fù)雜對(duì)象的建造過(guò)程抽象出來(lái)(抽象類別),使這個(gè)抽象過(guò)程的不同實(shí)現(xiàn)方法可以構(gòu)造出不同表現(xiàn)(屬性)的對(duì)象。
一步一步創(chuàng)建一個(gè)復(fù)雜的對(duì)象,允許用戶只通過(guò)指定復(fù)雜對(duì)象的類型和內(nèi)容就可以構(gòu)建它們,而不需要知道內(nèi)部的具體構(gòu)建細(xì)節(jié)。
類圖:

- Product(產(chǎn)品): 具體的產(chǎn)品對(duì)象
- Builder(抽象建造者): 創(chuàng)建一個(gè)產(chǎn)品對(duì)象的各個(gè)部件指定的接口/抽象類。
- ConcreteBuilder(具體建造者): 實(shí)現(xiàn)接口,構(gòu)建和裝配各個(gè)部件。
- Director(指揮者): 構(gòu)建一個(gè)使用Builder接口的對(duì)象,負(fù)責(zé)控制產(chǎn)品對(duì)象的生產(chǎn)過(guò)程,隔離了客戶與對(duì)象的生產(chǎn)過(guò)程。
建造者模式解法
代碼:
House類(Product產(chǎn)品)
public class House {
private String baise;
private String wall;
private String roof;
}
HouseBuilder類(Builder抽象建造者)
public abstract class HouseBuilder {
protected House house = new House();
//將建造的流程寫(xiě)好, 抽象的方法
public abstract void buildBasic();
public abstract void buildWalls();
public abstract void buildRoof();
//建造房子好, 將產(chǎn)品(房子) 返回
public House buildHouse() {
return house;
}
}
3.Bungalow類(ConcreteBuilder具體建造者A)
public class Bungalow extends HouseBuilder {
@Override
public void buildBasic() {
System.out.println("平房打地基");
}
@Override
public void buildWalls() {
System.out.println("平房砌墻");
}
@Override
public void buildRoof() {
System.out.println("平房封頂");
}
}
4.Villa類(ConcreteBuilder具體建造者B)
public class Villa extends HouseBuilder {
@Override
public void buildBasic() {
System.out.println("別墅打地基");
}
@Override
public void buildWalls() {
System.out.println("別墅砌墻");
}
@Override
public void buildRoof() {
System.out.println("別墅封頂");
}
}
5.HouseDirector類(Director指揮者)
public class HouseDirector {
HouseBuilder houseBuilder = null;
//構(gòu)造器傳入 houseBuilder
public HouseDirector(HouseBuilder houseBuilder) {
this.houseBuilder = houseBuilder;
}
//通過(guò)setter 傳入 houseBuilder
public void setHouseBuilder(HouseBuilder houseBuilder) {
this.houseBuilder = houseBuilder;
}
//如何處理建造房子的流程,交給指揮者
public House constructHouse() {
houseBuilder.buildBasic();
houseBuilder.buildWalls();
houseBuilder.buildRoof();
return houseBuilder.buildHouse();
}
}
客戶端調(diào)用
public class Client {
public static void main(String[] args) {
//蓋平房
Bungalow commonHouse = new Bungalow();
//準(zhǔn)備創(chuàng)建房子的指揮者
HouseDirector houseDirector = new HouseDirector(commonHouse);
//完成蓋房子,返回產(chǎn)品(普通房子)
House house = houseDirector.constructHouse();
System.out.println("--------------------------");
//蓋別墅
Villa highBuilding = new Villa();
//重置建造者
houseDirector.setHouseBuilder(highBuilding);
//完成蓋房子,返回產(chǎn)品(高樓)
houseDirector.constructHouse();
}
}
運(yùn)行結(jié)果:

總結(jié)
- 客戶端不必知道產(chǎn)品內(nèi)部組成的細(xì)節(jié),將產(chǎn)品本身與產(chǎn)品的創(chuàng)建過(guò)程解耦,使得相同的創(chuàng)建過(guò)程可以創(chuàng)建不同的產(chǎn)品對(duì)象。
- 將復(fù)雜產(chǎn)品的創(chuàng)建步驟分解在不同的方法中,使得創(chuàng)建過(guò)程更加清晰。
- 使用不同的具體建造者即可得到不同的產(chǎn)品對(duì)象。
- 增加新的具體建造者無(wú)須修改原有代碼。
- 若產(chǎn)品間的差異很大,則不適合使用建造者模式。
- 抽象工廠模式VS建造者模式
抽象工廠模式是對(duì)產(chǎn)品家族的創(chuàng)建,一個(gè)產(chǎn)品家族是一系列產(chǎn)品:具有不同分類維度的產(chǎn)品組合,采用抽象工廠模式不需要關(guān)心構(gòu)建過(guò)程,只關(guān)心什么產(chǎn)品由什么工廠生產(chǎn)即可。
而建造者模式則是要求按照指定的藍(lán)圖建造產(chǎn)品,它的主要目的是通過(guò)組裝零配件而產(chǎn)生一個(gè)新產(chǎn)品。
本篇文章就到這里了,希望能給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
基于SpringBoot實(shí)現(xiàn)用戶身份驗(yàn)證工具
這篇文章主要介紹了基于SpringBoot實(shí)現(xiàn)的用戶身份驗(yàn)證工具,非常不錯(cuò),具有參考借鑒價(jià)值 ,需要的朋友可以參考下2018-04-04
解決mybatis plus字段為null或空字符串無(wú)法保存到數(shù)據(jù)庫(kù)的問(wèn)題
這篇文章主要介紹了解決mybatis plus字段為null或空字符串無(wú)法保存到數(shù)據(jù)庫(kù)的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-02-02
通過(guò)java字節(jié)碼分析學(xué)習(xí)對(duì)象初始化順序
今天用了jmock對(duì)進(jìn)行單元測(cè)試編碼,發(fā)現(xiàn)一個(gè)比較奇怪的語(yǔ)法,static使用方法,見(jiàn)下面例子2013-11-11
基于java實(shí)現(xiàn)DFA算法代碼實(shí)例
這篇文章主要介紹了基于java實(shí)現(xiàn)DFA算法代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09

