责任链模式(Chain of Responsibility)是一种行为设计模式,其主要思想是创建多个对象并通过每个对象对其封装的方式检查一个顺序,然后决定哪一个对象应该处理这个请求。这种模式可以动态地修改处理顺序。
简单来说,责任链模式就是一个对象链对请求进行处理,但实际的处理者是其中的一个对象,而不是全部。在责任链模式中,请求者并不知道处理者是哪一个,只知道请求在责任链中被处理了。处理者也只知道处理了请求,而并不知道自己是责任链中的哪一个环节。
这个模式的好处是减少了请求者与处理者之间的耦合,提高了软件的健壮性。同时当处理逻辑发生改变时,只需要调整处理顺序,或者增加/删除处理者,而不需要修改原有代码,符合开闭原则。
以下是Go如何实现责任链模式的示例:
首先,我们通过定义接口来定义一个请求的处理者
type Handler interface {
ServeHTTP(content string) string
}
其次,我们实现几个具体的处理者。
type EmailHandler struct {
Next Handler
}
func (h *EmailHandler) ServeHTTP(content string) string {
if strings.Contains(content, "email") {
return "Email handled"
}
if h.Next != nil {
return h.Next.ServeHTTP(content)
}
return "End of chain, no handler for " + content
}
type PhoneHandler struct {
Next Handler
}
func (h *PhoneHandler) ServeHTTP(content string) string {
if strings.Contains(content, "phone") {
return "Phone handled"
}
if h.Next != nil {
return h.Next.ServeHTTP(content)
}
return "End of chain, no handler for " + content
}
在此例中,如果发送过来的请求含有"email",则EmailHandler会处理这个请求,如果请求包含"phone",则PhoneHandler会处理这个请求。如果都不包含,则返回没有找到处理器的信息。通过Next字段,我们将处理器链接起来,形成了一条责任链。
测试代码如下:
func main() {
emailHandler := &EmailHandler{
Next: nil,
}
phoneHandler := &PhoneHandler{
Next: emailHandler,
}
fmt.Println(phoneHandler.ServeHTTP("email"))
}
当执行上述的main方法时,首先是PhoneHandler接收到请求,但请求中并没有包含"phone",因此它会调用Next即EmailHandler的ServeHTTP方法,由EmailHandler来处理这个请求,因此控制台输出"Email handled"。