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ì)模式——行為型模式(下)

迭代器模式

提供一種方法順序訪問一個(gè)聚合對象中的各個(gè)元素,而又不需要暴露該對象的內(nèi)部表示

適用場景

  1. 把在元素之間游走的責(zé)任交給迭代器怎虫,而不是集合對象

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

type IAggregate interface {
    Iterator() IIterator
}

type IIterator interface {
    HasNext() bool
    Current() int
    Next() bool
}

type Aggregate struct {
    Container []int
}

func (a *Aggregate) Iterator() IIterator {
    i := new(Iterator)
    i.aggregate = a
    return i
}

type Iterator struct {
    cursor    int
    aggregate *Aggregate
}

func (i *Iterator) HasNext() bool {
    return i.cursor < len(i.aggregate.Container)-1
}

func (i *Iterator) Current() int {
    return i.aggregate.Container[i.cursor]
}

func (i *Iterator) Next() bool {
    if i.HasNext() {
        i.cursor++
        return true
    }
    return false
}

func main() {
    a := &Aggregate{Container: []int{1, 2, 3, 4}}

    it := a.Iterator()

    for {
        fmt.Printf("current: %d\n", it.Current())
        if it.HasNext() {
            it.Next()
        } else {
            break
        }
    }
}

迭代器模式優(yōu)點(diǎn)

  1. 它支持不同的方式遍歷集合對象
  2. 迭代器簡化了聚合類
  3. 在同一個(gè)聚合上面可以有多個(gè)遍歷
  4. 迭代器模式中暑认,新增聚合類和迭代器都很方便督暂,無需新增代碼

迭代器模式缺點(diǎn)

  1. 增加新的聚合類需要增加對應(yīng)新的迭代器

解釋器模式

提供如何定義語言的文法,以及對語言句子的解釋方法

適用場景

  1. 一般應(yīng)用于編譯器穷吮、規(guī)則引擎逻翁、正則表達(dá)式等功能

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

type Expression interface {
    Interpret(context string) bool
}

type TerminalExpression struct {
    Context string
}

func (e *TerminalExpression) Interpret(context string) bool {
    return strings.Contains("good", context)
}

type OrExpression struct {
    Expr1 Expression
    Expr2 Expression
}

func NewOrExpression(e1, e2 Expression) *OrExpression {
    return &OrExpression{
        Expr1: e1,
        Expr2: e2,
    }
}

func (e *OrExpression) Interpret(context string) bool {
    return e.Expr1.Interpret(context) || e.Expr2.Interpret(context)
}

func main() {
    g := &TerminalExpression{Context: "go"}
    d := &TerminalExpression{Context: "god"}

    o := NewOrExpression(g, d)

    r := o.Interpret("god")

    fmt.Println(r)
}

解釋器模式優(yōu)點(diǎn)

  1. 可擴(kuò)展性高、靈活
  2. 易于實(shí)現(xiàn)簡單的文法

解釋器模式缺點(diǎn)

  1. 可使用場景少
  2. 復(fù)雜文法較難維護(hù)

命令模式

將一個(gè)請求封裝為一個(gè)對象捡鱼,使發(fā)出請求的責(zé)任和執(zhí)行請求的責(zé)任分割開

適用場景

  1. 對行為進(jìn)行記錄八回、撤銷、重做等處理

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

type Order interface {
    Execute()
}

type Runner struct{}

func (r *Runner) Execute() {
    fmt.Println("running")
}

type Control struct {
    Cmd Order
}

func (c *Control) SetCmd(cmd Order) {
    c.Cmd = cmd
}

func (c *Control) Do() {
    c.Cmd.Execute()
}

func main() {
    c := Control{}
    r := Runner{}
    c.SetCmd(&r)
    c.Do()
}

命令模式優(yōu)點(diǎn)

  1. 通過引入中間件降低了系統(tǒng)的耦合度
  2. 擴(kuò)展性良好驾诈,且滿足"開閉原則"

命令模式缺點(diǎn)

  1. 每一個(gè)具體操作都需要設(shè)計(jì)一個(gè)具體命令類缠诅,增加了系統(tǒng)復(fù)雜度

責(zé)任鏈模式

將所有請求的處理者通過前一對象記住其下一個(gè)對象的引用而連成一條鏈,直到請求被處理為止

適用場景

  1. 多個(gè)對象可以處理一個(gè)請求乍迄,但是具體由誰來執(zhí)行在運(yùn)行時(shí)自動確定
  2. 可動態(tài)指定一組對象處理請求或添加新的處理者

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

type Context struct {
    Data string
}

type Handle interface {
    Handle(context Context)
    SetNext(handle Handle)
    GetNext() (next Handle, ok bool)
}

type LogHandle struct {
    next Handle
}

func (h *LogHandle) Handle(c Context) {
    fmt.Printf("日志:%s", c.Data)
    if next, ok := h.GetNext(); ok {
        next.Handle(c)
    }
}

func (h *LogHandle) SetNext(next Handle) {
    h.next = next
}

func (h *LogHandle) GetNext() (next Handle, ok bool) {
    if h.next != nil {
        return h.next, true
    }
    return nil, false
}

type AuthHandle struct {
    next Handle
}

func (h *AuthHandle) Handle(c Context) {
    fmt.Printf("權(quán)限:%s", c.Data)
    if next, ok := h.GetNext(); ok {
        next.Handle(c)
    }
}

func (h *AuthHandle) SetNext(next Handle) {
    h.next = next
}

func (h *AuthHandle) GetNext() (next Handle, ok bool) {
    if h.next != nil {
        return h.next, true
    }
    return nil, false
}

func main() {
    auth := AuthHandle{}
    log := LogHandle{}
    log.SetNext(&auth)
    context := Context{Data: "test"}

    log.Handle(context)
}

責(zé)任鏈模式優(yōu)點(diǎn)

  1. 降低了對象間的耦合度
  2. 增強(qiáng)了系統(tǒng)的可擴(kuò)展性
  3. 增強(qiáng)了給對象指派職責(zé)的靈活性
  4. 簡化了對象間的連接

責(zé)任鏈模式缺點(diǎn)

  1. 不能保證每個(gè)請求一定被處理
  2. 責(zé)任鏈建立的合理性靠客戶端保證管引,增加了客戶端的復(fù)雜性
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市闯两,隨后出現(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ī)與錄音蕉拢,去河邊找鬼特碳。 笑死,一個(gè)胖子當(dāng)著我的面吹牛晕换,可吹牛的內(nèi)容都是我干的午乓。 我是一名探鬼主播,決...
    沈念sama閱讀 40,251評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼闸准,長吁一口氣:“原來是場噩夢啊……” “哼益愈!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起夷家,我...
    開封第一講書人閱讀 39,129評論 0 276
  • 序言:老撾萬榮一對情侶失蹤蒸其,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后瘾英,有當(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
  • 正文 我和宋清朗相戀三年缺谴,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片耳鸯。...
    茶點(diǎn)故事閱讀 39,902評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡湿蛔,死狀恐怖,靈堂內(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. 我叫王不留,地道東北人像棘。 一個(gè)月前我還...
    沈念sama閱讀 48,025評論 2 370
  • 正文 我出身青樓稽亏,卻偏偏與公主長得像,于是被迫代替她去往敵國和親缕题。 傳聞我的和親對象是個(gè)殘疾皇子截歉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評論 2 354

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