go语言设计模式之职责链模式

226 阅读2分钟

职责链模式(Chain of Responsibility)

职责链模式是一种行为设计模式,定义了一系列对象,每个对象可以选择处理某个请求,也可以将该请求传给链中的下一个对象。

职责链模式通常用于处理复杂的请求处理场景,可以有效的降低代码耦合度。

模式结构

职责链模式包含以下角色:

  • 抽象处理器(Handler):定义出一个处理请求的接口。
  • 具体处理器(ConcreteHandler):实现抽象处理器的接口,处理它所负责的请求。如果不处理该请求,则把请求转发给它的后继者。
  • 客户端(Client):创建处理器对象,并将请求发送到某个处理器。

示例代码

下面我们通过一个包裹快递的例子来演示如何使用职责链模式。

  • 具体处理器(ConcreteHandler)
package main

import "fmt"

type Handler interface {
    SetNext(handler Handler) // 设置下一个处理器
    Handle(request int) // 处理请求
}

type ExpressHandler struct {
    NextHandler Handler
}

type LocalHandler struct {
    NextHandler Handler
}

type RemoteHandler struct {
    NextHandler Handler
}

func (eh *ExpressHandler) SetNext(handler Handler) {
    eh.NextHandler = handler
}

func (lh *LocalHandler) SetNext(handler Handler) {
    lh.NextHandler = handler
}

func (rh *RemoteHandler) SetNext(handler Handler) {
    rh.NextHandler = handler
}

func (eh *ExpressHandler) Handle(request int) {
    // 处理包裹快递
    if request <= 10 {
        fmt.Println("ExpressHandler: 小于等于10,我来处理。")
    } else {
        if eh.NextHandler != nil {
            eh.NextHandler.Handle(request)
        }
    }
}

func (lh *LocalHandler) Handle(request int) {
    // 处理本地快递
    if request > 10 && request <= 100 {
        fmt.Println("LocalHandler: 大于10小于等于100,我来处理。")
    } else {
        if lh.NextHandler != nil {
            lh.NextHandler.Handle(request)
        }
    }
}

func (rh *RemoteHandler) Handle(request int) {
    // 处理远程快递
    if request > 100 {
        fmt.Println("RemoteHandler: 大于100了,我来处理。")
    } else {
        if rh.NextHandler != nil {
            rh.NextHandler.Handle(request)
        }
    }
}
  • 客户端(Client)
package main

func main() {
    expressHandler := &ExpressHandler{}
    localHandler := &LocalHandler{}
    remoteHandler := &RemoteHandler{}

    expressHandler.SetNext(localHandler)
    localHandler.SetNext(remoteHandler)

    // 处理请求
    requests := []int{5, 50, 150}
    for _, request := range requests {
        expressHandler.Handle(request)
    }
}
  • 输出结果
ExpressHandler: 小于等于10,我来处理。
LocalHandler: 大于10小于等于100,我来处理。
RemoteHandler: 大于100了,我来处理。

从输出结果可以看出,包裹数小于等于10时,由快递员处理;包裹数大于10但小于等于100时,由本地快递处理;包裹数大于100时,由远程快递处理。