一個(gè)栗子:
身為一個(gè)程序猿,連續(xù)加班25天,在打了25個(gè)噴嚏之后溉贿,你終于意識到自己感冒了,為了能夠省下錢買阿珂288塊的暗夜貓娘皮膚浦旱,你決定去指定的定點(diǎn)醫(yī)院宇色。然后你就開始了漫長的排隊(duì)和沒完沒了的交錢、看診程序。
一般來說流程是這樣:
首先病人必須先掛號宣蠕,然后門診例隆。如果醫(yī)生要求化驗(yàn),病人必須首先劃價(jià)抢蚀,然后繳費(fèi)镀层,才可以到化驗(yàn)部門做化驗(yàn)∶笄化驗(yàn)后再回到門診室唱逢。
交互圖如下:
這個(gè)時(shí)候你一定覺得這樣來回的跑來跑去,并且要跟各個(gè)部門的人員打交道很麻煩屋休,然后你又想到了體檢的時(shí)候vip用戶可以有一個(gè)專門的小護(hù)士帶路坞古,安排各種行程。你不由得心生幻想劫樟,也希望有個(gè)年輕貌美單身的小護(hù)士代替來辦這些事痪枫,你只要輕聲細(xì)語的跟這個(gè)年輕貌美單身的小護(hù)士說話就可以了,于是出現(xiàn)了如下情景:
定義:
隱藏了系統(tǒng)的復(fù)雜性叠艳,并向客戶端提供了一個(gè)可以訪問系統(tǒng)的接口奶陈。這種類型的設(shè)計(jì)模式屬于結(jié)構(gòu)性模式。為子系統(tǒng)中的一組接口提供了一個(gè)統(tǒng)一的訪問接口附较,這個(gè)接口使得子系統(tǒng)更容易被訪問或者使用
結(jié)構(gòu):
角色:
門面(Facade)角色 :客戶端可以調(diào)用這個(gè)角色的方法吃粒。此角色知曉相關(guān)的(一個(gè)或者多個(gè))子系統(tǒng)的功能和責(zé)任。在正常情況下拒课,本角色會將所有從客戶端發(fā)來的請求委派到相應(yīng)的子系統(tǒng)去声搁。
子系統(tǒng)(SubSystem)角色 :可以同時(shí)有一個(gè)或者多個(gè)子系統(tǒng)。每個(gè)子系統(tǒng)都不是一個(gè)單獨(dú)的類捕发,而是一個(gè)類的集合(如上面的子系統(tǒng)就是由ModuleA、ModuleB很魂、ModuleC三個(gè)類組合而成)扎酷。每個(gè)子系統(tǒng)都可以被客戶端直接調(diào)用,或者被門面角色調(diào)用遏匆。子系統(tǒng)并不知道門面的存在法挨,對于子系統(tǒng)而言,門面僅僅是另外一個(gè)客戶端而已幅聘。
源碼:
public class Guahao {
public void guahao() {
System.out.println("掛號");
}
}
public class Jiaofei {
public void jiaofei() {
System.out.println("繳費(fèi)");
}
}
public class Kanzhen {
public void kanzhen() {
System.out.println("看診");
}
public void kaiyao() {
System.out.println("開藥");
}
}
public class Nayao {
public void nayao() {
System.out.println("拿藥");
}
}
/**
* Facade
* 門面類
* @version 1.0
*
*/
public class Facade {
public void kanbing() {
Guahao guahao = new Guahao();
Jiaofei jiaofei = new Jiaofei();
Nayao nayao = new Nayao();
Kanzhen kanzhen = new Kanzhen();
guahao.guahao();
jiaofei.jiaofei();
kanzhen.kanzhen();
jiaofei.jiaofei();
nayao.nayao();
}
}
運(yùn)行結(jié)果:
優(yōu)點(diǎn):
松散耦合
門面模式松散了客戶端與子系統(tǒng)的耦合關(guān)系凡纳,讓子系統(tǒng)內(nèi)部的模塊能更容易擴(kuò)展和維護(hù)。簡單易用
門面模式讓子系統(tǒng)更加易用帝蒿,客戶端不再需要了解子系統(tǒng)內(nèi)部的實(shí)現(xiàn)荐糜,也不需要跟眾多子系統(tǒng)內(nèi)部的模塊進(jìn)行交互,只需要跟門面類交互就可以了。更好的劃分訪問層次
通過合理使用Facade暴氏,可以幫助我們更好地劃分訪問的層次延塑。有些方法是對系統(tǒng)外的,有些方法是系統(tǒng)內(nèi)部使用的答渔。把需要暴露給外部的功能集中到門面中关带,這樣既方便客戶端使用,也很好地隱藏了內(nèi)部的細(xì)節(jié)沼撕。
缺點(diǎn):
- 如果增加新的子系統(tǒng)可能需要修改外觀類或客戶端的源代碼宋雏,這樣就違背了”開閉原則“(不過這點(diǎn)也是不可避免)。