Go语言设计模式之责任链模式其实很多人不知道,责任链模式是我们工作中经常遇到的模式,特别是web后端工程师,我们工作中每

我们先来看一下责任链模式(ChainOfResponsibilityDesignPattern)的英文介绍:Avoidcouplingthesenderofarequesttoitsreceiverbygivingmorethanoneobjectachancetohandletherequest.Chainthereceivingobjectsandpasstherequestalongthechainuntilanobjecthandlesit.

翻译成中文就是:将请求的发送和接收解耦,让多个接收对象都有机会处理这个请求。将这些接收对象串成一条链,并沿着这条链传递这个请求,直到链上的某个接收对象能够处理它为止。

这么说比较抽象,用更加容易理解的话来进一步解读一下。在责任链模式中,一个请求过来,会有多个处理器(也就是刚刚定义中说的“接收对象”)依次处理同一个请求。即请求先经过A处理器处理,然后再把请求传递给B处理器,B处理器处理完后再传递给C处理器,以此类推,形成一个链条。链条上的每个处理器各自承担各自的处理职责,所以叫作责任链模式。

责任链模式(ChainOfResponsibilityDesignPattern)的整体结构如下:

我们依据标准的UML图,写出一个具体的例子(对应UML图):

首先定义一个接口IHandler:

typeIHandlerinterface{ SetNext(handlerIHandler) Handle(scoreint)}然后分别构建三个不同的实现:ConcreteHandler1

typeConcreteHandler2struct{ NextIHandler}func(c*ConcreteHandler2)Handle(scoreint){ ifscore>0{ fmt.Println("ConcreteHandler2处理") return } ifc.Next!=nil{ c.Next.Handle(score) } return}func(c*ConcreteHandler2)SetNext(handlerIHandler){ c.Next=handler}ConcreteHandler3

typeConcreteHandler3struct{ NextIHandler}func(c*ConcreteHandler3)Handle(scoreint){ ifscore==0{ fmt.Println("ConcreteHandler3处理") return } ifc.Next!=nil{ c.Next.Handle(score) } return}func(c*ConcreteHandler3)SetNext(handlerIHandler){ c.Next=handler}最后是main函数:

ConcreteHandler2处理2.3改进版demo通过以上标准例子不难发现:main函数承接了很多client自身之外的“额外工作”:构建和拼接组装责任链,这不利于后续client端的使用和扩展:一不小心可能责任链拼就接错了或者拼接少节点了。我们可以对UML做一个改进:增加一个节点管理模块。改进图如下:

对比上文的uml图,新增加了一个ChainHandler结构体用来管理拼接的Handler,client端无需了解Handler的业务,Handler的组合可以使用链表,也可以使用数组(当前用了数组)。具体实现如下:先定义Handler接口:

typeHandlerinterface{ Handle(scoreint)}然后分别实现Handler接口的三个结构体:ConcreteHandlerOne

typeConcreteHandlerTwostruct{ Handler}func(c*ConcreteHandlerTwo)Handle(scoreint){ ifscore>0{ fmt.Println("ConcreteHandler2处理") return }}ConcreteHandlerThree

typeConcreteHandlerThreestruct{ Handler}func(c*ConcreteHandlerThree)Handle(scoreint){ ifscore==0{ fmt.Println("ConcreteHandler3处理") return }}main函数调用(client调用):

日常工作中出现的责任链模式(ChainOfResponsibilityDesignPattern)一般都是以上这种包含Hanlder管理的模式。

在日常框架和语言基础库中,经常能够看到很多场景使用了责任链模式。

可以对比改进版demo的uml图,beego的过滤器就是按照这种模式来设计的(当前参照的beego版本是2.0)。

调用端首先是过滤器的注册:

web.InsertFilter("/v2/api/*",web.BeforeRouter,auth.AuthAPIFilter)然后在github.com/beego/beego/v2@v2.0.3/server/web/router.go的ControllerRegister结构体的serveHttp函数中

Handler接口很简单

//HandleFuncdefinehowtoprocesstherequesttypeHandleFuncfunc(ctx*beecontext.Context) ... typeFilterFunc=HandleFunc3.1.3Handler接口实现接口的实现扩展比较灵活,直接把用户定义的函数作为接口的实现。与client端中的过滤器注册联动。

//过滤器注册web.InsertFilter("/v2/api/*",web.BeforeRouter,auth.AuthAPIFilter)//自定义过滤器varAuthAPIFilter=func(ctx*context.Context){ isAccess:=validateAccess(ctx) if!isAccess{ res,_:=json.Marshal(r) ctx.WriteString(string(res)) //ctx.Redirect(401,"/401") }}3.1.4Handler管理Handler的管理模块是在github.com/beego/beego/v2@v2.0.3/server/web/router.go的中的FilterRouter和ControllerRegister两个结构体中

typeHandlerinterface{ ServeHTTP(ResponseWriter,*Request)}为了扩展方便,在使用过程中并非直接使用,而是中间又加了一层抽象层(相当于Java中的抽象类了,Go中没有抽象类)

//TheHandlerFunctypeisanadaptertoallowtheuseof//ordinaryfunctionsasHTTPhandlers.Iffisafunction//withtheappropriatesignature,HandlerFunc(f)isa//Handlerthatcallsf.typeHandlerFuncfunc(ResponseWriter,*Request)//ServeHTTPcallsf(w,r).func(fHandlerFunc)ServeHTTP(wResponseWriter,r*Request){ f(w,r)}3.2.3Handler接口实现与上文中提到的Beego的过滤器类似,Go的Handler设计的也非常容易扩展,用户自定义的请求处理函数Handler都会变成Handler的子类。

typeServeMuxstruct{ musync.RWMutex mmap[string]muxEntry es[]muxEntry//sliceofentriessortedfromlongesttoshortest. hostsbool//whetheranypatternscontainhostnames}typemuxEntrystruct{ hHandler patternstring}其中,用户自定以的处理函数都被封装到了muxEntry结构体的Handler中,一个自定义的函数对应一个muxEntry,ServeMux使用hashmap对muxEntry集合进行管理(上文的beego中是使用的链表,上文demo中使用了数组)。当webserver接收到请求的时候,ServeMux会根据hashmap找到相应的handler然后处理。

责任链模式的基本思想就是要处理的请求(通常会是结构体,然后作为函数参数);依次经过多个处理对象处理,这些处理函数可以动态的添加和删除,具备很高的灵活性和扩展性,通常会对这些处理函数做统一处理,存储方式一般是通过链表、数组、hashmap等存储结构。

THE END
1.GoRevelFilter(过滤器)源码分析黑暗伯爵说到revel框架很多重要的东西都Filters过滤器链中处理。 Ftilers链是整个revel框架的处理核心。 Filters(过滤器链) filter.go package revel type Filter func(c *Controller, filterChain []Filter) // Filters 为全局的过滤器链 // 项目初始化时Filters就会被设置 ...https://www.cnblogs.com/hangxin1940/p/3266311.html
2.Go技术日报(20211212看透Go 对象内部细节的神器 十、脑子进煎鱼了 动图图解!既然IP层会分片,为什么TCP层也还要分段? 十一、Golang梦工厂 gin框架是如何处理请求参数? GOCN每日新闻--2021-12-05 1.一种轻量级的 Elasticsearch 替代方案,需要最少的资源 2.详解布隆过滤器原理与实现 ...https://mdnice.com/writing/c764102f39614e898a4742d33abc4cb4
3.详解布隆过滤器的原理和实现OSCHINA根据上面的算法原理可以知道实现布隆过滤器主要做三件事情: k 次散列函数计算出 k 个位点。 插入时将位数组中 k 个位点的值设置为 1。 查询时根据 1 的计算结果判断 k 位点是否全部为 1,否则表示该元素一定不存在。 下面来看看 go-zero 是如何实现的: ...https://my.oschina.net/kevwan/blog/5346451
4.美国GOGO美国GO公司,将为您提供全面的解决方案。无论您需要 整套设备,还是定制设备-GO都可以为您提供 合适的解决方案。与之配套的 系列附件,保证了在各种应用场合的高效和安全运行。操作安全是 重要的。http://gochina.jiawushop.com/
5.GO阀门美国GO调压阀GO中国阀门减压阀调压阀背压阀美国GO公司,是标准化和专业压力调节阀门、隔膜阀和过滤器的设计商和制造商,产品适用于分析、仪器仪表、石化、石油和天然气以及特种气体行业。GO调节器和阀门旨在满足广泛的应用,控制压力,同时适应许多气体和液体的低到中等流速。http://goregulator.jiawutech.com/
6.美国GORegulator隔膜阀阀液压/气动产品/品牌中心GO Regulator是球的压力调节器、隔膜阀、过滤器的设计者和生产商,生产各种用于石油化工、石油天然气和特种气体行业的仪器仪表,GO Regulator的调节器和阀门可以满足广泛的应用范围http://www.victortrading.com.cn/chanpinfenlei/yeya_qidong/fa/14838.html
1.事件过滤器go在配置文件填写对应通信方式的 middlewares.filter 即可开启事件过滤器,启动时会读取该文件中定义的过滤规则(使用 JSON 编写),若文件不存在,或过滤规则语法错误,则不会启用事件过滤器。 事件过滤器会处理所有事件(包括心跳事件在内的元事件),请谨慎使用!! https://docs.go-cqhttp.org/guide/eventfilter.html
2.Web模块Web过滤器《Beegov2.0.7使用手册》Web 过滤器 filter是我们 Beego 提供的 AOP 的解决方案。不仅仅是在web中应用,也是在其余模块中应用。 在Beego 中,filter承担两方面的职责,一方面是作为AOP的实现,一方面是作为请求生命周期的钩子。所以要理解filter要先理解 Beego 的请求处理过程。 简单例子 ...https://www.bookstack.cn/read/beego-2.0.7-zh/web-filter-README.md
3.Golang设计模式之过滤器模式过滤器模式 GitHub代码链接[https://github.com/lee820/design-pattern-go] 什么是过滤器模式 这种模式运行开发人员使用不同的标...https://www.jianshu.com/p/027d22076e8d
4....高纯减压阀GO背压阀GO隔膜阀GO过滤器价格厂家GO隔膜阀,GO气动减压阀、GO高纯减压阀、GO背压阀、GO隔膜阀、GO过滤器,GO的产品应用领域包括仪器仪表、石油天然气、化工、工业气体、半导体等。尤其在分析仪表样品预处理应用,GO减压阀产品以其***的产品性能和可靠性,成为ABB、Siemens、Servomex等集成产品的供应商。展开 ...https://www.china.cn/jianyafa/5019545658.html
5.golang实现微信小程序商城后台系统(moshopserver)GolangNideshop中做了一些设计,有些接口即使token过期也能访问,不需要提示用户再次登录。moshopserver中也实现了这个功能。采用了beego中的过滤器: 1 beego.InsertFilter("/api/*", beego.BeforeExec, services.FilterFunc, true, true) 使用的是BeforeExec参数,这个阶段Router已经识别出了Controller和Action的具体类型,我们...https://www.jb51.net/article/181220.htm
6.探索老爹冰棒店ToGo!游戏预告:创新服装过滤器功能揭晓我们非常高兴地在今天向大家展示,我们在《老爹冰棒店To Go》中引入了一项全新的功能——服装过滤器。 这个新功能将帮助你在游戏中更轻松、更快捷地找到你心仪的服装。 我们知道,由于我们的服装选择非常丰富,有时候要在众多的选项中找到最合适的衣服可能会有些困难。 https://www.zhaosy.com/raiders/221007.html
7.Golang中高效布隆过滤器基于CACH技术的实现原理。Golanggolang中高效布隆过滤器基于cach技术的实现原理 布隆过滤器是一种基于哈希函数的空间效率非常高的数据结构,用于判断某个元素是否存在于一个集合中。由于其空间复杂度很低,因此在大规模数据处理、网络爬虫、信息过滤等领域中广泛应用。在Golang中,高效布隆过滤器的实现原理主要基于CACH技术。 CACH(Concurrency-Aware ...https://m.php.cn/faq/563424.html
8....玻璃茶漏茶斗茶滤网过滤器滤茶器茶具配件GO厨具 > 茶具 > 茶具配件 > 金灶(KAMJOVE) > 金灶(KAMJOVE)GO-08 金灶官方旗舰店 金灶(KAMJOVE) 玻璃茶漏茶斗 茶滤网过滤器滤茶器茶具... 京东价 ¥ 促销 展开促销 配送至 --请选择-- 支持https://item.jd.com/14320072326.html
9.GoBloomFilter(基于GoogleGuava的布隆过滤器)本文代码思路来源于Guava,对java版用golang进行了重写,对于超精度的get与put进行了优化,与java版本各有优劣,相关数据对比在文末。 布隆过滤器:以牺牲少量正确率为代价,利用较少的空间实现O(1)的hash查询方式。 与bitmap不同点在于,bloomfilter通过多个哈希映射,利用一组bit判断元素是否存在。 https://linzhaoqi.com/archives/gobloomfilter
10.用Wireshark监听WIFI通讯只有wireshark截获到四个eapol消息之后,才可以解密通信数据。在过滤器里输入eapol来显示截获到的eapol 8.使用其他的过滤器来查看在这台wifi上的通信了 如果把gopro换成一台普通的wifi路由器,那么,你就可以看到所有连接在这台wifi上的设备的所有通信了。 https://www.douban.com/note/328099725/
11.gopkg/awesomegocn:golang的一些第三方包合集awesomeAwesome Go 内容 音频和音乐 身份验证和OAuth 区块链 Bot建设 构建自动化 命令行 高级控制台用户界面 标准CLI 配置 持续集成 CSS预处理器 数据结构与算法 Bit-packing and Compression 位集合 布隆和布谷鸟过滤器 数据结构和算法集合 迭代器 地图 杂项数据结构和算法 可空类型 队列 集 文本分析 树 管道 数...https://gitea.mrx.ltd/Go-pkg/awesome-go-cn/src/commit/e8d611d3e3fab446cc5a17afd68ea816bed7dc04
12.吐血整理超全golang面试题合集+golang学习指南+golang知识...利用golang特性,设计一个QPS为500的服务器 为什么gc会让程序变慢 开多个线程和开多个协程会有什么区别 两个interface{} 能不能比较 必须要手动对齐内存的情况 go栈扩容和栈缩容,连续栈的缺点 golang怎么做代码优化 golang隐藏技能:怎么访问私有成员 常用官方包说明 ...https://blog.51cto.com/u_15102959/2637222
13.GitHubgo-svg 操作 https://github.com/ajstarks/svgo go 布隆过滤器实现 https://github.com/AndreasBriese/bbloom json相关 https://github.com/bitly/go-simplejson LRU Cache实现 https://github.com/bluele/gcache https://github.com/hashicorp/golang-lru go运行时函数替换 https://github.com/bouk/monke...https://github.com/cnlong/golangFamily
14.C级T级A级H级主营产品:空压机整机 压缩空气净化设备 空压机保养耗材空气过滤器,机油过滤器,油气分离器芯 润滑油 阀件 传感器 供应商:金华市鑫格林机电设备有限公司 更多优质供应商> 所在地:中国 浙江 金华 联系人:范建伟 您的联系方式已覆盖全网,展示在其他同类产品页面 ...http://china.makepolo.com/product-detail/100735906953.html
15.beego的controller设计beego过滤器 beego的Flash数据 beego的URL构建 beego多种格式数据输出 beego表单数据验证 beego错误处理 beego日志处理 beego的model设计 beego的model设计概述 beego的ORM使用 beego的CRUD操作 beego高级查询 beego原生SQL查询 beego构造查询 beego事务处理 beego模型定义 beego命令模式...https://www.w3cschool.cn/kityl/controller-design-for-beego.html
16.Beego高频面试题和答案数据路由和控制器自动化 内置ORM支持 简单易用的API 可扩展的插件系统 如何在Beego中设置路由规则? 在Beego中,可以使用一个名为Router的函数来设置路由规则。例如,beego.Router("/hello/:name", &controllers.HelloController{})可以将请求路由到名为name的参数的值上。 Beego中的过滤器是什么? 过滤器是一种机...https://maimai.cn/article/detail?fid=1779169498&efid=CaaxNkia7WXmVZXzVhYb0A
17.SFFILTER过滤器德国SFFILTER型号SFFILTER价格SF-FILTER过滤器滤芯是过滤器的心脏,顾名思义为滤芯。滤芯的主要也是过滤器的主要原理,是为了净化原生态的资源和资源的再利用,而需要的净化设备,滤芯一般主要用在油过滤、水过滤、空气过滤等过滤行业。除去过滤介质中少量杂质,可保护设备的正常工作或者空气的洁净,当流体经过过滤器中具有一定精度的滤芯后,其杂质被阻挡...http://www.wdutech.com/product/4577667/
18.Navigateto的继承者GoToMicrosoftLearn新的Go To体验添加的过滤器 你可以使用快捷键Ctrl+,打开Go To,这样会在你正在编辑的文档上创建一个搜索框。“Go To”是下面这些功能的一个统称: 移至某一行 (Ctrl +G)- 迅速跳转到你当前文档中的某一行。 转至所有 (Ctrl + ,) 或者 (Ctrl + T)- 和之前的Navigate To的功能相似,搜索结果包括以下内容...https://docs.microsoft.com/zh-tw/archive/blogs/c/navigate-to%E7%9A%84%E7%BB%A7%E6%89%BF%E8%80%85-go-to