定义
老规矩,开局3连问
什么叫做责任链呢? 责任链又是干嘛的呢? 我用它能干嘛呢?
责任链模式是一种行为设计模式, 允许你将请求沿着处理者链进行发送。 收到请求后, 每个处理者均可对请求进行处理, 或将其传递给链上的下个处理者。
使用场景
目前你正在开发一个会员系统,产品说,你校验下,用户年龄必须满14周岁才能开会员
对于聪明的你,这不轻轻松松吗?一个简单的校验而已。1天开发上线,完美!
上线第二天,产品说:哥哥,咱们还得再加一个校验,支付的时候咱们先看下他账户余额是不是充足的
你一想简单,2天开发上线,就加一个if的事情
上线第二天,产品又来了:好哥哥,在加一个校验呗,咱们校验下,他如果创建了支付单,但是没支付,又创建支付的情况,咱们给点提示。
轻轻松松在加个if,上线
过了N天,产品过来说:好哥哥,咱们得加个防重啊,好多用户短期内不断点击开vip,但是不支付啊
此时,你发现了不对,这个校验好像是捅了马蜂窝一样,这if写到什么时候是个头呢。
刚好,你想起了一个非常合适的设计模式-责任链
校验逻辑不就是这样的吗?遇到一个校验没通过就返回,一个通过开始校验下一个,像是一个链表一样,向下传递,于是开始了华丽的操作
先来个处理者接口
type IChecker interface {
Check(ctx context.Context, req interface) error
}
咱们这个处理者,就返回一个错误就行了,遇到错就返回,这叫做知错就改
在来个结构体
// BaseChecker 支持责任链
type BaseChecker struct {
}
在来个校验链
// CheckerChain 定义了校验器链
type CheckerChain struct {
baseCheckers []IChecker
}
//为了正式点初始化对象不能少
func NewCheckerChain() *CheckerChain {
return &CheckerChain{}
}
添加校验器
// AddBaseCheckers 添加普通校验器
func (vc *CheckerChain) AddBaseCheckers(v ...IChecker) *CheckerChain {
vc.baseCheckers = append(vc.baseCheckers, v...)
return vc
}
//校验逻辑
func (vc *CheckerChain) Check(ctx context.Context) error {
// 先执行普通校验
for _, checker := range vc.baseCheckers {
if err := checker.Check(ctx); err != nil {
return err
}
}
return nil
}
来2个实现
type AgeChecker struct {
BaseChecker
}
func NewAgeChecker() *AgeChecker {
return &AgeChecker{}
}
func (c AgeChecker) Check(ctx context.Context, req interface) error {
if req.age < 14 {
return errors.New("Age less than 14")
}
return nil
}
二号实验品
type AmountChecker struct {
BaseChecker
}
func NewAmountChecker() *AmountChecker {
return &AgeChecker{}
}
func (c AmountChecker) Check(ctx context.Context, req interface) error {
if req.amount < 100 {
return errors.New("Insufficient account balance")
}
return nil
}
使用
//构建校验项
checkerChain := checkerCreate.NewCheckerChain()
checkerChain.AddBaseCheckers(checkerCreate.NewAgeChecker()).
AddBaseCheckers(checkerCreate.AmountChecker())
//开始校验
err := checkerChain.Check(ctx, req)
改造完,一看代码简直完美,完工,下班~