观前科普
责任链模式是一种行为型设计模式,当请求被发送到一个处理器链上,链上的每一个处理器都可以决定是否处理该请求,或者传递给链上的下一个处理对象
自然,责任链模式的每一个处理器都实现自同一个处理器接口,而且都可以自行决定处理。
在这个案例中,由于场景的特殊性,我们让责任链模式的每一个处理器都进行过滤操作,直到链上所有的处理器都完成过滤,则就实现了过滤链。
小明用Go语言写了一个过滤器链代码:
type Filter[T any] interface { // 过滤器接口,所有实现该接口的结构体都要实现该接口定义的Filtering方法
Filtering(input T) T
}
type FilterChain[T any] struct {
filter Filter[T
next *FilterChain[T
}
/**
* Go没有类的概念,
* 主要还是因为Go的研发团队认为Go应当是一门简洁的语言,
* 因此Go不是一门面向对象的编程语言,或者说不纯粹面向对象,
* 但Go语言仍然可以像使用类那样使用类似构造函数的工厂函数,
* 然而Go没法强制用户必须使用工厂函数,因为结构体本身不是类,
* 为此使用该结构体时,仍然要对该结构体声明的结构体变量进行类型检查
*/
func FilterChnain[T any](filter Filter[T]) *FilterChain[T] {
return &FilterChain {
filter: filter
}
}
func (fc *FilterChain[T any]) SetNext(next *FilterChain[T]) {
fc.next = next
}
func (fc *FilterChain[T any]) Filtering(input T) T{
/**
* 与通常的面向对象的编程语言不同,
* Go不是一个面向对象的语言,
* 但仍然可以实现接口,
* 只不过Go语言采用一种隐形实现的机制,
* 任何结构体,如果定义了该接口所有同名的函数,
* 编译器在类型检查的时候,会默认这个结构体实现自该接口
*/
if fc.filter != nil {
input = fc.filter.Filtering(input)
}
if fc.next != nil {
input = fc.next.Filtering(input)
}
return input
示例:获取一个价格处于60~80元、评分等级不低于4的黑色产品列表
package main
import ("fmt")
type Product struct {
Price float32
Brand string
Color string
SalesVolume int
GradingScale int
}
type PriceFilter struct {}
type ColorFilter struct {}
type GradingScaleFilter struct {}
func (p *PriceFilter) Filtering(input Product) Product {
if input.Price >=60 && input.Print <=80 {
return input
} else {
return nil
}
}
func (c *ColorFilter) Filtering(input Product) Product {
if input.Color == "Black" {
return input
} else {
return nil
}
}
func (gs *GradingScaleFilter) Filtering (input Product) Product {
if input.GradingScale >= 4 && input.GradingScale <=5{
return input
} else {
return nil
}
}
func main () {
priceFilter := &PriceFilter{}
colorFilter := &ColorFilter{}
gradingScaleFilter := &GradingScaleFilter{}
filterChain := FilterChain(priceFilter).SetNext(FilterChain(colorFilter)).SetNext(FilterChain(gradingScaleFilter))
//这里用我手机里的某购物软件的信息
orginalProducts := []Product{
{71.5,"某品牌的衣服1","Black",7783,5},
{80.07,"某品牌的衣服1","Yello",2356,4},
{29.8,"某品牌的书","Orange",2333,2},
{6.93,"某品牌的书","Black",4399,4},
{55.92,"某品牌的衣服2","Yello",8848,5},
{58,"某品牌的衣服2","Blue",1234,4},
{17.99,"某垃圾品牌的保健品","Pink",1000000,5}, // 疑似刷的
{71.59,"某垃圾品牌的矫正器","Green",17000,5}, // 疑似刷的
{3.18,"某垃圾品牌的牙刷","Red",40000,5}, //疑似刷的
{3.43,"某垃圾品牌的护肤品","Black",33000,5} //疑似刷的
}
filteredProducts := []Product
for _, product := range orginalProducts {
if filterChain.Filtering(product) != nil {
filteredProducts = append(filteredProducts, product)
}
}
for _, product := range filteredProducts {
fmt.Printf("这是一个价格为%.2f,品牌为%s,颜色为%s,销量为%d,评分等级为%d的商品\n", product.Price, product.Brand, product.Color, product.SalesVolume, product.GradingScale)
}
}