在Golang中您应该知道的责任链模式(设计模式06)

解锁责任的力量:发现Go的责任链模式如何简化复杂的请求处理场景。

联系作者@:微信公众号,Medium,LinkedIn,Twitter

golang golang-chain-of-responsibility-pattern(from github.com/MariaLetta/free-gophers-pack)|300

责任链模式(Chain of Responsibility)是一种行为型设计模式,用于将请求沿着处理链传递,链中的每个处理器可以处理请求,也可以将其传递给下一个处理器。

背景

在实际开发中,我们常常会遇到需要对请求进行分级处理的场景。例如,日志系统需要根据日志级别分发日志,或者权限校验系统需要根据角色和权限链逐级验证。

通过责任链模式,我们可以避免硬编码多个 if-elseswitch 逻辑,将责任分离到不同的处理器中,增强代码的可读性和扩展性。

Go 是一门注重简洁和高效的语言,其接口、组合以及函数式编程特性非常适合实现责任链模式。与 Java 等面向对象语言的复杂继承方式不同,Go 倾向于通过接口组合和函数链式调用实现灵活的责任链。

设计思想

我们将设计一个支持动态扩展的责任链,其中每个处理器都可以:

  1. 对请求进行处理。
  2. 决定是否将请求传递给下一个处理器。

Go 的实现中,我们将采用以下两种方法:

  1. 接口实现:通过定义处理器接口来构建责任链。
  2. 函数式实现:使用 Go 的函数类型和闭包实现链式调用。

示例:实现一个简单的日志处理系统

需求:根据日志的级别(Info、Warning、Error),由不同的处理器处理日志。

运行结果

1
2
3
[INFO] This is an info log.
[WARNING] This is a warning log.
[ERROR] This is an error log.

基于函数的实现

哪种实现更具 Go 特色?

  • 接口实现:更适合处理复杂责任链场景,便于扩展和实现更多行为。
  • 函数实现:更加简洁,用 Go 的函数式编程特性,能快速实现轻量级责任链。

适用场景

我们从概念中可以看出责任链模式有如下明显的优势:

  • 按职责划分:解耦
  • 对象链:逻辑清晰

适用场景:

  • 多个对象可以处理一个请求:当不确定哪个对象会处理请求时,可以使用责任链模式。
  • 动态指定一组对象来处理请求:可以根据需要添加或修改链中的处理者。
  • 解耦请求发送者与接收者:发送者无需知道哪个具体对象会处理请求,从而降低了系统耦合度。

那么可以有如下一些具体场景:

  1. 日志处理:根据日志级别分派处理器。
  2. 权限校验:按照角色和权限链逐级验证用户操作权限。
  3. 请求过滤:在 Web 框架中对请求进行逐层拦截和处理。

标准库实现

在 Go 的 net/http 标准库中,处理 HTTP 请求时可以通过多层中间件实现责任链模式。

每个中间件(如 LoggingMiddlewareAuthMiddleware)充当一个“处理节点”,可以选择处理请求或将请求传递到下一个中间件。

总结

责任链模式在 Go 中的实现可以充分利用其简洁的接口和函数特性,使得代码更加清晰、高效。
在需要动态指定一组对象来处理请求的场景中非常有效,例如在中间件、事件处理和请求分发等应用中。

更多内容

最近文章:

随机文章:


更多该系列文章,参考medium链接:

https://wesley-wei.medium.com/list/you-should-know-in-golang-e9491363cd9a

参考

An Easy Guide to Learn Chain of Responsibility in Golang | by Leonard Yeo | Level Up Coding
Golang Pattern: Chain of Responsibility | by Achmad Rizki Nur Fauzie | Medium

English post: https://programmerscareer.com/golang-chain-of-responsibility-pattern/
作者:微信公众号,Medium,LinkedIn,Twitter
发表日期:原文在 2024-12-10 00:50 时创作于 https://programmerscareer.com/zh-cn/golang-chain-of-responsibility-pattern/
版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证

golang中你应该知道的协程协作知识 在Golang中您应该知道的对象池模式(设计模式05)

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×