Golang面試寶典——Go語言實(shí)現(xiàn)23種設(shè)計(jì)模式之行為型模式(上)

關(guān)于Golang面試寶典

最近幾年叠殷,Go的熱度持續(xù)飆升,國內(nèi)外很多大公司都在大規(guī)模的使用Go揖庄。Google是Go語言誕生的地方栗菜,其他公司如Facebook、騰訊蹄梢、阿里疙筹、字節(jié)跳動、百度禁炒、京東而咆、小米等都在擁抱和轉(zhuǎn)向Go。Go語言的開源項(xiàng)目也非常多幕袱,如kubernetes暴备、docker、etcd们豌。

隨著市場對Go語言人才需求的增長涯捻,很多開發(fā)者都投入了Go語言的懷抱。本系列文章將以第一視角與大家一同開始Golang的面試之路望迎,希望大家能夠有所收獲障癌,拿下心儀的offer。

使用Go實(shí)現(xiàn)23種設(shè)計(jì)模式——行為型模式(下)

訪問者模式

在不改變各元素的類的前提下定義作用于這些元素的新操作

適用場景

  1. 數(shù)據(jù)結(jié)構(gòu)相對穩(wěn)定的對象辩尊,且需要經(jīng)常在此結(jié)構(gòu)上定義新操作

Go語言實(shí)現(xiàn)

type Number struct {
    Numbers []int
}

func (n *Number) Do(v IVisitor) {
    v.Do(n.Numbers)
}

type IVisitor interface {
    Do([]int)
}

type AddVisitor struct{}

func (v *AddVisitor) Do(numbers []int) {
    sum := 0
    for _, n := range numbers {
        sum += n
    }
    fmt.Printf("sum: %d\n", sum)
}

type TimesVisitor struct{}

func (v *TimesVisitor) Do(numbers []int) {
    res := 1
    for _, n := range numbers {
        res *= n
    }
    fmt.Printf("res: %d\n", res)
}

func main() {
    a := Number{Numbers: []int{1, 2, 3, 4}}
    a.Do(&AddVisitor{})
    a.Do(&TimesVisitor{})
}

訪問者模式優(yōu)點(diǎn)

  1. 增加新的操作簡單

訪問者模式缺點(diǎn)

  1. 增加新的數(shù)據(jù)結(jié)構(gòu)困難

模板方法模式

定義一個操作中的算法的骨架涛浙,而將一些步驟延遲到子類中,使得子類可以不改變一個算法的結(jié)構(gòu)即可重定義該算法的某些特定步驟

適用場景

  1. 模板模式解決了一些方法通用对省,卻在每個子類都重新寫一遍的這些方法

Go語言實(shí)現(xiàn)

type Notify struct {
}

func (n *Notify) Send() {
    fmt.Println("send error")
}

type SMSNotify struct {
    Notify
}

func (n *SMSNotify) Send() {
    fmt.Println("send sms success")
}

type EMailNotify struct {
    Notify
}

func (n *EMailNotify) Send() {
    fmt.Println("send email success")
}

func main() {
    a := SMSNotify{}
    a.Send()

    b := EMailNotify{}
    b.Send()
}

模板方法模式優(yōu)點(diǎn)

  1. 封裝不變的部分蝗拿,擴(kuò)展可變部分
  2. 提取公共代碼,便于維護(hù)
  3. 行為由父類控制蒿涎,子類實(shí)現(xiàn)

模板方法模式缺點(diǎn)

  1. 每一個不同的實(shí)例哀托,都需要一個子類來實(shí)現(xiàn),導(dǎo)致類的個數(shù)增加

策略模式

定義一系列的算法劳秋,把它們一個個封裝起來仓手,并且使它們可相互替換

適用場景

  1. 一個類定義了多種行為,并且這些行為以多個if...else形式出現(xiàn)

Go語言實(shí)現(xiàn)

type Operation interface {
    Do(n1, n2 int) int
}

type OperationAdd struct {
}

func NewOperationAdd() *OperationAdd {
    return &OperationAdd{}
}

func (o *OperationAdd) Do(n1, n2 int) int {
    return n1 + n2
}

type OperationSubtract struct {
}

func NewOperationSubtract() *OperationSubtract {
    return &OperationSubtract{}
}

func (o *OperationSubtract) Do(n1, n2 int) int {
    return n1 -n2
}

type Context struct {
    operation Operation
}

func NewContext(operation Operation) *Context {
    return &Context{operation: operation}
}

func (c *Context) Do(n1, n2 int) int {
    return c.operation.Do(n1, n2)
}

func main() {
    a := NewContext(NewOperationAdd())
    a.Do(1, 2)
    b := NewContext(NewOperationSubtract())
    b.Do(3, 1)
}

策略模式優(yōu)點(diǎn)

  1. 避免使用多重判斷語句
  2. 算法可自由切換
  3. 擴(kuò)展性好

策略模式缺點(diǎn)

  1. 客戶端需要理解所有策略算法的區(qū)別玻淑,以便選擇合適的算法類
  2. 策略類很多嗽冒,增加維護(hù)難度

狀態(tài)模式

允許一個對象在其內(nèi)部狀態(tài)改變時改變它的行為

適用場景

  1. 代碼中包含大量與對象狀態(tài)有關(guān)的條件語句

Go語言實(shí)現(xiàn)

type Account struct {
    Action State
    status string
}

func NewAccount(status string) *Account {
    a := &Account{status: status}
    a.initState()
    return a
}

func (a *Account) initState() {
    if a.status == "normal" {
        a.Action = &NormalState{}
    } else {
        a.Action = &BannedState{}
    }
}

type State interface {
    Login()
}

type NormalState struct{}

func (s *NormalState) Login() {
    fmt.Println("登陸成功")
}

type BannedState struct{}

func (s *BannedState) Login() {
    fmt.Println("賬號封禁,禁止登陸")
}

func main() {
    a := NewAccount("normal")
    a.Action.Login()
}

狀態(tài)模式優(yōu)點(diǎn)

  1. 封裝了轉(zhuǎn)換規(guī)則
  2. 將所有與狀態(tài)相關(guān)的行為放到一個類中补履,方便的增加狀態(tài)
  3. 允許狀態(tài)轉(zhuǎn)換邏輯和狀態(tài)對象合成一體添坊,而不是巨大的條件語句塊

狀態(tài)模式缺點(diǎn)

  1. 增加了系統(tǒng)中類和對象的個數(shù),導(dǎo)致系統(tǒng)運(yùn)行開銷變大
  2. 狀態(tài)模式的結(jié)構(gòu)與實(shí)現(xiàn)都比較復(fù)雜
  3. 對"開閉原則"的支持不友好
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末箫锤,一起剝皮案震驚了整個濱河市贬蛙,隨后出現(xiàn)的幾起案子雨女,更是在濱河造成了極大的恐慌,老刑警劉巖阳准,帶你破解...
    沈念sama閱讀 217,657評論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件氛堕,死亡現(xiàn)場離奇詭異,居然都是意外死亡野蝇,警方通過查閱死者的電腦和手機(jī)讼稚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來绕沈,“玉大人锐想,你說我怎么就攤上這事∑叱澹” “怎么了痛倚?”我有些...
    開封第一講書人閱讀 164,057評論 0 354
  • 文/不壞的土叔 我叫張陵规婆,是天一觀的道長澜躺。 經(jīng)常有香客問我,道長抒蚜,這世上最難降的妖魔是什么掘鄙? 我笑而不...
    開封第一講書人閱讀 58,509評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮嗡髓,結(jié)果婚禮上操漠,老公的妹妹穿的比我還像新娘。我一直安慰自己饿这,他們只是感情好浊伙,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著长捧,像睡著了一般嚣鄙。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上串结,一...
    開封第一講書人閱讀 51,443評論 1 302
  • 那天哑子,我揣著相機(jī)與錄音,去河邊找鬼肌割。 笑死卧蜓,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的把敞。 我是一名探鬼主播弥奸,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼奋早!你這毒婦竟也來了盛霎?” 一聲冷哼從身側(cè)響起冒冬,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎摩渺,沒想到半個月后简烤,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,561評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡摇幻,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評論 3 335
  • 正文 我和宋清朗相戀三年横侦,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片绰姻。...
    茶點(diǎn)故事閱讀 39,902評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡枉侧,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出狂芋,到底是詐尸還是另有隱情榨馁,我是刑警寧澤,帶...
    沈念sama閱讀 35,621評論 5 345
  • 正文 年R本政府宣布帜矾,位于F島的核電站翼虫,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏屡萤。R本人自食惡果不足惜珍剑,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望死陆。 院中可真熱鬧招拙,春花似錦、人聲如沸措译。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽领虹。三九已至规哪,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間掠械,已是汗流浹背由缆。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留猾蒂,地道東北人均唉。 一個月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像肚菠,于是被迫代替她去往敵國和親舔箭。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評論 2 354

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