外觀模式

外觀模式是一種結(jié)構(gòu)類型的代碼設(shè)計(jì)模式之一缺虐,其目的是提供一個(gè)簡(jiǎn)單的接口或門(mén)面(客戶端視角的“外觀”)芜壁,使復(fù)雜的子系統(tǒng)或類更易于使用。它通過(guò)封裝子系統(tǒng)中的一組接口志笼,并提供一個(gè)統(tǒng)一的接口,簡(jiǎn)化了對(duì)子系統(tǒng)的操作把篓。

模式實(shí)例代碼

使用Go語(yǔ)言實(shí)現(xiàn)外觀模式的示例代碼:

package main

import "fmt"

// SubsystemA 是子系統(tǒng)A
type SubsystemA struct{}

func (s *SubsystemA) MethodA() {
    fmt.Println("SubsystemA: MethodA")
}

// SubsystemB 是子系統(tǒng)B
type SubsystemB struct{}

func (s *SubsystemB) MethodB() {
    fmt.Println("SubsystemB: MethodB")
}

// Facade 是外觀
type Facade struct {
    subsystemA *SubsystemA
    subsystemB *SubsystemB
}

func NewFacade() *Facade {
    return &Facade{
        subsystemA: &SubsystemA{},
        subsystemB: &SubsystemB{},
    }
}

// Execute 執(zhí)行操作
func (f *Facade) Execute() {
    f.subsystemA.MethodA()
    f.subsystemB.MethodB()
}

func main() {
    facade := NewFacade()
    facade.Execute()
}

上述代碼中纫溃,SubsystemA和SubsystemB是兩個(gè)子系統(tǒng),它們分別實(shí)現(xiàn)了不同的方法韧掩。Facade是外觀紊浩,它封裝了SubsystemA和SubsystemB,提供了一個(gè)統(tǒng)一的接口Execute()來(lái)執(zhí)行操作。通過(guò)外觀模式坊谁,客戶端只需與外觀對(duì)象交互费彼,而無(wú)需直接與子系統(tǒng)進(jìn)行交互,從而簡(jiǎn)化了操作的復(fù)雜性口芍。在示例代碼中箍铲,客戶端只需要?jiǎng)?chuàng)建外觀對(duì)象并調(diào)用Execute()方法即可完成操作。

外觀模式代碼擴(kuò)展性

考慮到代碼的未來(lái)的擴(kuò)展性鬓椭,外觀對(duì)象本身通常是保持不變的颠猴,不應(yīng)該隨著子系統(tǒng)的變化而頻繁修改。外觀模式充當(dāng)了客戶端和子系統(tǒng)之間的中介小染,隱藏了子系統(tǒng)的復(fù)雜性翘瓮,客戶端只需與外觀對(duì)象進(jìn)行交互。

如果后續(xù)需要擴(kuò)展或修改子系統(tǒng)中的某個(gè)部分裤翩,可以通過(guò)以下方式來(lái)實(shí)現(xiàn):

  1. 添加新的子系統(tǒng):如果需要添加新的功能或子系統(tǒng)资盅,可以創(chuàng)建一個(gè)新的子系統(tǒng),并在外觀對(duì)象中添加相應(yīng)的方法踊赠,將新的子系統(tǒng)集成到外觀中呵扛。這樣客戶端仍然只需要與外觀對(duì)象進(jìn)行交互,而不需要關(guān)心新的子系統(tǒng)的具體實(shí)現(xiàn)臼疫。
  2. 修改子系統(tǒng)的行為:如果需要修改子系統(tǒng)的行為择份,可以直接在子系統(tǒng)內(nèi)部進(jìn)行修改,而不會(huì)影響外觀對(duì)象或客戶端的代碼烫堤。外觀對(duì)象僅僅是對(duì)子系統(tǒng)的調(diào)用進(jìn)行封裝荣赶,修改子系統(tǒng)的行為不會(huì)改變外觀對(duì)象的接口。
  3. 繼承和重寫(xiě):可以通過(guò)繼承外觀對(duì)象的方式來(lái)擴(kuò)展或修改外觀對(duì)象的行為鸽斟。通過(guò)創(chuàng)建一個(gè)新的子類拔创,并重寫(xiě)需要修改的方法,可以實(shí)現(xiàn)對(duì)外觀對(duì)象行為的定制富蓄。這種方式可以支持對(duì)外觀對(duì)象的擴(kuò)展和靈活性剩燥。

總之,通過(guò)保持外觀對(duì)象的穩(wěn)定性和封裝性立倍,可以更容易地?cái)U(kuò)展和修改子系統(tǒng)灭红,同時(shí)確保客戶端的代碼不需要修改口注。

比如未來(lái)需要添加新的子系統(tǒng)C時(shí)变擒,可以按照以下步驟對(duì)外觀模式進(jìn)行擴(kuò)展:
首先,在現(xiàn)有的代碼基礎(chǔ)上創(chuàng)建一個(gè)新的子系統(tǒng)C:

// 新增子系統(tǒng)C
type SubsystemC struct{}

func (s *SubsystemC) MethodC() {
    fmt.Println("SubsystemC: MethodC")
}

然后寝志,在外觀對(duì)象中添加對(duì)子系統(tǒng)C的集成和方法調(diào)用:

// Facade 是外觀
type Facade struct {
    subsystemA *SubsystemA
    subsystemB *SubsystemB
    subsystemC *SubsystemC    //擴(kuò)展
}

func NewFacade() *Facade {
    return &Facade{
        subsystemA: &SubsystemA{},
        subsystemB: &SubsystemB{},
        subsystemC: &SubsystemC{},  //擴(kuò)展
    }
}

// Execute 執(zhí)行操作
func (f *Facade) Execute() {
    f.subsystemA.MethodA()
    f.subsystemB.MethodB()
    f.subsystemC.MethodC()    //擴(kuò)展
}

現(xiàn)在娇斑,外觀對(duì)象就包含了子系統(tǒng)C策添,并在Execute()方法中調(diào)用了SubsystemC的方法。

客戶端使用代碼保持不變毫缆,仍只需創(chuàng)建外觀對(duì)象并調(diào)用Execute()方法唯竹,即可同時(shí)調(diào)用子系統(tǒng)A、B和C的相應(yīng)方法苦丁,完成操作:

// 客戶端操作保持不變
func main() {
    facade := NewFacade()
    facade.Execute()
}

與中介者模式的不同

外觀模式和中介者模式的確有一些相似之處浸颓,但它們的主要目的和實(shí)現(xiàn)方式有所不同。

外觀模式的主要目的是簡(jiǎn)化客戶端與復(fù)雜子系統(tǒng)之間的交互芬骄,提供一個(gè)統(tǒng)一的接口或門(mén)面猾愿,隱藏子系統(tǒng)的復(fù)雜性。外觀模式通過(guò)封裝子系統(tǒng)账阻,使得客戶端可以更方便地使用子系統(tǒng)的功能蒂秘,但客戶端仍然直接與外觀對(duì)象進(jìn)行交互。

中介者模式的主要目的是減少對(duì)象之間的直接耦合淘太,將對(duì)象間的交互通過(guò)一個(gè)中介對(duì)象進(jìn)行協(xié)調(diào)姻僧。中介者模式通過(guò)將對(duì)象間的通信集中到一個(gè)中介對(duì)象中,從而降低了對(duì)象間的依賴關(guān)系蒲牧。對(duì)象不再直接相互引用撇贺,而是通過(guò)中介者對(duì)象來(lái)進(jìn)行通信。

以下是一個(gè)使用Go語(yǔ)言實(shí)現(xiàn)外觀模式和中介者模式進(jìn)行對(duì)比的示例代碼:

// 外觀模式示例

// SubsystemA 是子系統(tǒng)A
type SubsystemA struct{}

func (s *SubsystemA) MethodA() {
    fmt.Println("SubsystemA: MethodA")
}

// SubsystemB 是子系統(tǒng)B
type SubsystemB struct{}

func (s *SubsystemB) MethodB() {
    fmt.Println("SubsystemB: MethodB")
}

// Facade 是外觀
type Facade struct {
    subsystemA *SubsystemA
    subsystemB *SubsystemB
}

func NewFacade() *Facade {
    return &Facade{
        subsystemA: &SubsystemA{},
        subsystemB: &SubsystemB{},
    }
}

func (f *Facade) Execute() {
    f.subsystemA.MethodA()
    f.subsystemB.MethodB()
}

// 中介者模式示例

// Mediator 是中介者
type Mediator struct {
    colleagueA *ColleagueA
    colleagueB *ColleagueB
}

func NewMediator() *Mediator {
    return &Mediator{}
}

func (m *Mediator) SetColleagueA(colleagueA *ColleagueA) {
    m.colleagueA = colleagueA
}

func (m *Mediator) SetColleagueB(colleagueB *ColleagueB) {
    m.colleagueB = colleagueB
}

func (m *Mediator) CoordinateA() {
    // 協(xié)調(diào)邏輯
    fmt.Println("Mediator: Coordinate A")
    m.colleagueB.ActionB()
}

func (m *Mediator) CoordinateB() {
    // 協(xié)調(diào)邏輯
    fmt.Println("Mediator: Coordinate B")
    m.colleagueA.ActionA()
}

// ColleagueA 是同事A
type ColleagueA struct {
    mediator *Mediator
}

func NewColleagueA(mediator *Mediator) *ColleagueA {
    return &ColleagueA{mediator: mediator}
}

func (c *ColleagueA) ActionA() {
    fmt.Println("ColleagueA: Action A")
    c.mediator.CoordinateA()
}

// ColleagueB 是同事B
type ColleagueB struct {
    mediator *Mediator
}

func NewColleagueB(mediator *Mediator) *ColleagueB {
    return &ColleagueB{mediator: mediator}
}

func (c *ColleagueB) ActionB() {
    fmt.Println("ColleagueB: Action B")
    c.mediator.CoordinateB()
}

func main() {
    // 外觀模式示例
    facade := NewFacade()
    facade.Execute()

    // 中介者模式示例
    mediator := NewMediator()
    colleagueA := NewColleagueA(mediator)
    colleagueB := NewColleagueB(mediator)
    mediator.SetColleagueA(colleagueA)
    mediator.SetColleagueB(colleagueB)
    colleagueA.ActionA()
}

在示例中冰抢,外觀模式通過(guò)封裝子系統(tǒng)A和B提供了統(tǒng)一的接口外觀對(duì)象(Facade)松嘶,客戶端只需與外觀對(duì)象進(jìn)行交互。

而中介者模式中挎扰,中介者對(duì)象(Mediator)被用來(lái)協(xié)調(diào)同事對(duì)象(ColleagueA和ColleagueB)之間的交互翠订,同事對(duì)象不直接耦合,而是通過(guò)中介者進(jìn)行通信遵倦。

總結(jié)起來(lái)尽超,外觀模式主要簡(jiǎn)化了客戶端與復(fù)雜子系統(tǒng)之間的接口,而中介者模式是用來(lái)減少對(duì)象間直接耦合梧躺。

總結(jié)

設(shè)計(jì)模式中的外觀模式旨在簡(jiǎn)化客戶端與復(fù)雜子系統(tǒng)之間的交互似谁,通過(guò)提供一個(gè)統(tǒng)一的接口或門(mén)面來(lái)隱藏子系統(tǒng)的復(fù)雜性。外觀模式封裝了子系統(tǒng)的一組接口掠哥,使客戶端更容易使用子系統(tǒng)的功能巩踏。

外觀對(duì)象本身在未來(lái)的擴(kuò)展中需要保持穩(wěn)定,如果需要擴(kuò)展或修改子系統(tǒng)的功能续搀,可以通過(guò)添加新的子系統(tǒng)塞琼、修改子系統(tǒng)的行為或通過(guò)繼承和重寫(xiě)外觀對(duì)象來(lái)實(shí)現(xiàn)。

與外觀模式相比目代,中介者模式的主要目的是減少對(duì)象之間的直接耦合屈梁。中介者模式通過(guò)引入一個(gè)中介者對(duì)象,將對(duì)象間的通信集中到該對(duì)象中進(jìn)行協(xié)調(diào)榛了,從而降低了對(duì)象間的依賴關(guān)系在讶。中介者模式中,對(duì)象不再直接相互引用霜大,而是通過(guò)中介者對(duì)象來(lái)進(jìn)行通信构哺。總的來(lái)說(shuō)战坤,外觀模式和中介者模式在目的和實(shí)現(xiàn)方式上存在區(qū)別:外觀模式簡(jiǎn)化了客戶端與復(fù)雜子系統(tǒng)之間的交互曙强,中介者模式減少對(duì)象間的直接耦合。外觀模式通過(guò)封裝子系統(tǒng)提供統(tǒng)一的接口途茫,而中介者模式通過(guò)引入中介者對(duì)象協(xié)調(diào)對(duì)象間的交互碟嘴。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市囊卜,隨后出現(xiàn)的幾起案子娜扇,更是在濱河造成了極大的恐慌,老刑警劉巖栅组,帶你破解...
    沈念sama閱讀 218,122評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件雀瓢,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡玉掸,警方通過(guò)查閱死者的電腦和手機(jī)刃麸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,070評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)司浪,“玉大人泊业,你說(shuō)我怎么就攤上這事《习粒” “怎么了脱吱?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,491評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)认罩。 經(jīng)常有香客問(wèn)我箱蝠,道長(zhǎng),這世上最難降的妖魔是什么垦垂? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,636評(píng)論 1 293
  • 正文 為了忘掉前任宦搬,我火速辦了婚禮,結(jié)果婚禮上劫拗,老公的妹妹穿的比我還像新娘间校。我一直安慰自己,他們只是感情好页慷,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,676評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布憔足。 她就那樣靜靜地躺著胁附,像睡著了一般。 火紅的嫁衣襯著肌膚如雪滓彰。 梳的紋絲不亂的頭發(fā)上控妻,一...
    開(kāi)封第一講書(shū)人閱讀 51,541評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音揭绑,去河邊找鬼弓候。 笑死,一個(gè)胖子當(dāng)著我的面吹牛他匪,可吹牛的內(nèi)容都是我干的菇存。 我是一名探鬼主播,決...
    沈念sama閱讀 40,292評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼邦蜜,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼依鸥!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起悼沈,我...
    開(kāi)封第一講書(shū)人閱讀 39,211評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤毕籽,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后井辆,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體关筒,經(jīng)...
    沈念sama閱讀 45,655評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,846評(píng)論 3 336
  • 正文 我和宋清朗相戀三年杯缺,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蒸播。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,965評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡萍肆,死狀恐怖袍榆,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情塘揣,我是刑警寧澤包雀,帶...
    沈念sama閱讀 35,684評(píng)論 5 347
  • 正文 年R本政府宣布,位于F島的核電站亲铡,受9級(jí)特大地震影響才写,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜奖蔓,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,295評(píng)論 3 329
  • 文/蒙蒙 一赞草、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧吆鹤,春花似錦厨疙、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,894評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)梗醇。三九已至,卻和暖如春撒蟀,著一層夾襖步出監(jiān)牢的瞬間婴削,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,012評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工牙肝, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人嗤朴。 一個(gè)月前我還...
    沈念sama閱讀 48,126評(píng)論 3 370
  • 正文 我出身青樓配椭,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親雹姊。 傳聞我的和親對(duì)象是個(gè)殘疾皇子股缸,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,914評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 1 場(chǎng)景問(wèn)題# 1.1 生活中的示例## 外觀模式在現(xiàn)實(shí)生活中的示例很多,比如:組裝電腦吱雏,通常會(huì)有兩種方案敦姻。 一個(gè)...
    七寸知架構(gòu)閱讀 6,239評(píng)論 7 57
  • 狀態(tài)模式代碼原型 解決的問(wèn)題:主要解決的是當(dāng)控制一個(gè)對(duì)象狀態(tài)轉(zhuǎn)換的條件表達(dá)式過(guò)于復(fù)雜時(shí)的情況。把狀態(tài)的判斷邏輯轉(zhuǎn)移...
    _涼笙閱讀 645評(píng)論 0 2
  • “設(shè)計(jì)二十三式之外觀模式” 01 意圖 外觀模式是一種結(jié)構(gòu)型設(shè)計(jì)模式歧杏, 能為程序庫(kù)镰惦、 框架或其他復(fù)雜類提供一個(gè)簡(jiǎn)單...
    昵稱有多帥閱讀 341評(píng)論 0 1
  • 前言 Android的設(shè)計(jì)模式系列文章介紹,歡迎關(guān)注犬绒,持續(xù)更新中: Android的設(shè)計(jì)模式-設(shè)計(jì)模式的六大原則一...
    四月葡萄閱讀 4,916評(píng)論 2 16
  • - 定義 隱藏系統(tǒng)的復(fù)雜性旺入,并向客戶端提供了一個(gè)客戶端可以訪問(wèn)系統(tǒng)的接口。這種類型的設(shè)計(jì)模式屬于結(jié)構(gòu)型模式凯力,它向現(xiàn)...
    jiahzhon閱讀 215評(píng)論 0 0