為子系統(tǒng)中的一組接口提供一個(gè)統(tǒng)一的入口。外觀模式定義了一個(gè)高層接口,這個(gè)接口使得這一子系統(tǒng)更加容易使用。
類型
結(jié)構(gòu)型
簡(jiǎn)介
引入外觀模式之后,增加新的子系統(tǒng)或者移除子系統(tǒng)都非常方便,客戶類無須進(jìn)行修改(或者極少的修改),只需要在外觀類中增加或移除對(duì)子系統(tǒng)的引用即可。
外觀模式中所指的子系統(tǒng)是一個(gè)廣義的概念,它可以是一個(gè)類、一個(gè)功能模塊、系統(tǒng)的一個(gè)組成部分或者一個(gè)完整的系統(tǒng)。子系統(tǒng)類通常是一些業(yè)務(wù)類,實(shí)現(xiàn)了一些具體的、獨(dú)立的業(yè)務(wù)功能。
參與者
- Facade(外觀角色):在客戶端可以調(diào)用它的方法,在外觀角色中可以知道相關(guān)的(一個(gè)或者多個(gè))子系統(tǒng)的功能和責(zé)任;在正常情況下,它將所有從客戶端發(fā)來的請(qǐng)求委派到相應(yīng)的子系統(tǒng)去,傳遞給相應(yīng)的子系統(tǒng)對(duì)象處理。
- SubSystem(子系統(tǒng)角色):在軟件系統(tǒng)中可以有一個(gè)或者多個(gè)子系統(tǒng)角色,每一個(gè)子系統(tǒng)可以不是一個(gè)單獨(dú)的類,而是一個(gè)類的集合,它實(shí)現(xiàn)子系統(tǒng)的功能;每一個(gè)子系統(tǒng)都可以被客戶端直接調(diào)用,或者被外觀角色調(diào)用,它處理由外觀類傳過來的請(qǐng)求;子系統(tǒng)并不知道外觀的存在,對(duì)于子系統(tǒng)而言,外觀角色僅僅是另外一個(gè)客戶端而已。
用法
舉例
在幾乎所有的軟件中都能夠找到外觀模式的應(yīng)用,如絕大多數(shù)B/S系統(tǒng)都有一個(gè)首頁或者導(dǎo)航頁面,大部分C/S系統(tǒng)都提供了菜單或者工具欄,在這里,首頁和導(dǎo)航頁面就是B/S系統(tǒng)的外觀角色,而菜單和工具欄就是C/S系統(tǒng)的外觀角色,通過它們用戶可以快速訪問子系統(tǒng),降低了系統(tǒng)的復(fù)雜程度。所有涉及到與多個(gè)業(yè)務(wù)對(duì)象交互的場(chǎng)景都可以考慮使用外觀模式進(jìn)行重構(gòu)。
適用場(chǎng)景
- 當(dāng)要為訪問一系列復(fù)雜的子系統(tǒng)提供一個(gè)簡(jiǎn)單入口時(shí)可以使用外觀模式。
- 客戶端程序與多個(gè)子系統(tǒng)之間存在很大的依賴性。引入外觀類可以將子系統(tǒng)與客戶端解耦,從而提高子系統(tǒng)的獨(dú)立性和可移植性。
- 在層次化結(jié)構(gòu)中,可以使用外觀模式定義系統(tǒng)中每一層的入口,層與層之間不直接產(chǎn)生聯(lián)系,而通過外觀類建立聯(lián)系,降低層之間的耦合度。
總結(jié)
外觀模式是一種使用頻率非常高的設(shè)計(jì)模式,它通過引入一個(gè)外觀角色來簡(jiǎn)化客戶端與子系統(tǒng)之間的交互,為復(fù)雜的子系統(tǒng)調(diào)用提供一個(gè)統(tǒng)一的入口,使子系統(tǒng)與客戶端的耦合度降低,且客戶端調(diào)用非常方便。外觀模式并不給系統(tǒng)增加任何新功能,它僅僅是簡(jiǎn)化調(diào)用接口。
優(yōu)點(diǎn)
- 它對(duì)客戶端屏蔽了子系統(tǒng)組件,減少了客戶端所需處理的對(duì)象數(shù)目,并使得子系統(tǒng)使用起來更加容易。通過引入外觀模式,客戶端代碼將變得很簡(jiǎn)單,與之關(guān)聯(lián)的對(duì)象也很少。
- 它實(shí)現(xiàn)了子系統(tǒng)與客戶端之間的松耦合關(guān)系,這使得子系統(tǒng)的變化不會(huì)影響到調(diào)用它的客戶端,只需要調(diào)整外觀類即可。
- 一個(gè)子系統(tǒng)的修改對(duì)其他子系統(tǒng)沒有任何影響,而且子系統(tǒng)內(nèi)部變化也不會(huì)影響到外觀對(duì)象。
缺點(diǎn)
- 不能很好地限制客戶端直接使用子系統(tǒng)類,如果對(duì)客戶端訪問子系統(tǒng)類做太多的限制則減少了可變性和靈活 性。
- 如果設(shè)計(jì)不當(dāng),增加新的子系統(tǒng)可能需要修改外觀類的源代碼,違背了開閉原則。