设计模式笔记 - 责任链模式

326 阅读2分钟

责任链模式是一种行为设计模式,允许你将请求沿着处理者链进行发送。收到请求后,每个处理者均可对请求进行处理,或将其传递给链上的下个处理者。


解决什么问题?

  • 当程序需要使用不同方式处理不同种类请求, 而且请求类型和顺序预先未知时, 可以使用责任链模式。
  • 当必须按顺序执行多个处理者时, 可以使用该模式。
  • 如果所需处理者及其顺序必须在运行时进行改变, 可以使用责任链模式。

实现步骤:

  • 定义统一处理接口
  • 责任链上各个实体类实现接口
  • 实体类调用下一个实体类处理请求或终止处理请求
  • 客户端创建责任链

优势:

  • 你可以控制请求处理的顺序。
  • 单一职责原则。 你可对发起操作和执行操作的类进行解耦。
  • 开闭原则。 你可以在不更改现有代码的情况下在程序中新增处理者。

劣势:

  • 部分请求可能未被处理。

下面是实现代码:

package main

import "fmt"

type request struct{ num int }

type handler interface {
	handle(*request)
}

type abstractStep struct {
	h handler
}

func (a *abstractStep) setNext(h handler) {
	a.h = h
}

func (a *abstractStep) handle(r *request) {
	if a.h != nil {
		a.h.handle(r)
	}
}

type stepOne struct {
	abstractStep
}

func (s *stepOne) handle(r *request) {
	if r.num == 1 {
		fmt.Printf("step one: %d + 1 = %d\n", r.num, r.num+1)
		r.num += 1
	}
	s.abstractStep.handle(r)
}

type stepTwo struct {
	abstractStep
}

func (s *stepTwo) handle(r *request) {
    fmt.Printf("step two: %d + 2 = %d\n", r.num, r.num+2)
	s.abstractStep.handle(r)
}

func main() {
	s1 := stepOne{}
	s2 := stepTwo{}

	s1.setNext(&s2)
	s2.setNext(nil)

	s1.handle(&request{num: 0})
	s1.handle(&request{num: 1})
}

输出:

step two: 0 + 2 = 2
step one: 1 + 1 = 2
step two: 2 + 2 = 4

参考