【go每日一题】 责任链模式的实现
责任链模式基本概念
责任链模式:Chain of Responsibility Patten 。就是将链中的每一个结点看做是一个对象,每个结点处理请求均不同,且内部自动维护一个下一个结点对象。当请求从链条的首端出发时,会沿着链的路径依次传递给每一个结点的对象,直到有对象处理这个请求为止。
就是说每个结点会处理一件事情,如果结点间出现异常,那么链路就会中断。
实现一个责任链模式
package test
import (
"errors"
"fmt"
"testing"
"time"
)
// 来一个请求,携带对应的权重
// 根据权重,一级一级地走责任链
type Request struct {
ID int
Weight int
MSG string
}
// 公共的抽象节点
type Handler interface {
Handle(request *Request) error
NextNode(node Handler)
}
// 节点1: mt 节点
type MTHandler struct {
next Handler
//suspend bool
}
func (mt *MTHandler) Handle(request *Request) error {
if request.Weight > 0 && request.Weight < 10 {
// 向mt发送一个审批,这里可以用channel阻塞mt的审批
fmt.Printf("mt handler is processing req: %d\n", request.ID)
// 如果出现异常,整个流程结束
} else if mt.next != nil {
mt.next.Handle(request)
} else {
fmt.Println("无节点可处理")
return errors.New("无可处理节点")
}
return nil
}
func (mt *MTHandler) NextNode(node Handler) {
mt.next = node
}
// 节点2: ld 节点
type LDHandler struct {
next Handler
suspend bool
}
func (ld *LDHandler) Handle(request *Request) error {
if request.Weight >= 10 && request.Weight < 30 {
// 向mt发送一个审批消息,这里可以用channel阻塞mt的审批
// 也可以使用数据库,这里卡着隔一段时间扫描数据库,查看审批状态
fmt.Printf("ld handler is processing req: %d\n", request.ID)
// 如果出现异常,整个流程结束
} else if ld.next != nil {
ld.next.Handle(request)
} else {
return errors.New("该权重无节点可以处理")
}
return nil
}
func (ld *LDHandler) NextNode(node Handler) {
ld.next = node
}
func TestResponsible(t *testing.T) {
req1 := &Request{
ID: 1,
Weight: 4,
MSG: "leave 4 days",
}
req2 := &Request{
ID: 2,
Weight: 20,
MSG: "leave 20 days",
}
reqCh := make(chan *Request, 10)
reqCh <- req1
reqCh <- req2
go func(reqCh chan *Request) {
mt := new(MTHandler)
ld := new(LDHandler)
mt.NextNode(ld)
for {
select {
case req := <-reqCh:
mt.Handle(req)
}
}
}(reqCh)
time.Sleep(time.Second * 3)
}
原文地址:https://blog.csdn.net/YiGeiGiaoGiao/article/details/144784890
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!