-
3.4 职责链模式
-
代码实现
首先我们看一下一个简单的实现模板,然后我们再看看实际上我们常用 web 框架 gin 当中是如何处理请求的
Code
// Package chain 职责链模式 // 🌰 假设我们现在有个校园论坛,由于社区规章制度、广告、法律法规的原因需要对用户的发言进行敏感词过滤 // 如果被判定为敏感词,那么这篇帖子将会被封禁 package chain // SensitiveWordFilter 敏感词过滤器,判定是否是敏感词 type SensitiveWordFilter interface { Filter(content string) bool } // SensitiveWordFilterChain 职责链 type SensitiveWordFilterChain struct { filters[] SensitiveWordFilter } // AddFilter 添加一个过滤器 func(c * SensitiveWordFilterChain) AddFilter(filter SensitiveWordFilter) { c.filters = append(c.filters, filter) } // Filter 执行过滤 func(c * SensitiveWordFilterChain) Filter(content string) bool { for _, filter: = range c.filters { // 如果发现敏感直接返回结果 if filter.Filter(content) { return true } } return false } // AdSensitiveWordFilter 广告 type AdSensitiveWordFilter struct {} // Filter 实现过滤算法 func(f * AdSensitiveWordFilter) Filter(content string) bool { // TODO: 实现算法 return false } // PoliticalWordFilter 政治敏感 type PoliticalWordFilter struct {} // Filter 实现过滤算法 func(f * PoliticalWordFilter) Filter(content string) bool { // TODO: 实现算法 return true }
单元测试
package chain import ( "testing" "github.com/stretchr/testify/assert" ) func TestSensitiveWordFilterChain_Filter(t * testing.T) { chain: = & SensitiveWordFilterChain {} chain.AddFilter( & AdSensitiveWordFilter {}) assert.Equal(t, false, chain.Filter("test")) chain.AddFilter( & PoliticalWordFilter {}) assert.Equal(t, true, chain.Filter("test")) }
Gin 的中间件实现
我们直接看一下 gin Context 的实现,其中 Next() 方法就是主要的执行方法,这里其实就是我们最上面说到的职责链模式的变体,因为它会在每一个处理函数中进行处理,而不是第一个接收到就停止了
type Context struct { // ... // handlers 是一个包含执行函数的数组 // type HandlersChain []HandlerFunc handlers HandlersChain // index 表示当前执行到哪个位置了 index int8 // ... } // Next 会按照顺序将一个个中间件执行完毕 // 并且 Next 也可以在中间件中进行调用,达到请求前以及请求后的处理 // Next should be used only inside middleware. // It executes the pending handlers in the chain inside the calling handler. // See example in GitHub. func(c * Context) Next() { c.index++ for c.index < int8(len(c.handlers)) { c.handlers[c.index](c) c.index++ } }
- 留下你的读书笔记
- 你还没登录,点击这里
-
用户笔记留言