【go每日一题】 责任链模式的实现

责任链模式基本概念

责任链模式:Chain of Responsibility Patten 。就是将链中的每一个结点看做是一个对象,每个结点处理请求均不同,且内部自动维护一个下一个结点对象。当请求从链条的首端出发时,会沿着链的路径依次传递给每一个结点的对象,直到有对象处理这个请求为止。

就是说每个结点会处理一件事情,如果结点间出现异常,那么链路就会中断。

实现一个责任链模式

go 复制代码
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)

}
相关推荐
FY_201811 小时前
Stable Baselines3中调度函数转换器get_schedule_fn 函数
开发语言·人工智能·python·算法
JienDa11 小时前
JienDa聊PHP:乡镇外卖跑腿小程序开发实战:基于PHP的乡镇同城O2O系统开发
开发语言·php
霸王大陆11 小时前
《零基础学 PHP:从入门到实战》模块十:从应用到精通——掌握PHP进阶技术与现代化开发实战-1
android·开发语言·php
老华带你飞12 小时前
旅游|基于Java旅游信息推荐系统(源码+数据库+文档)
java·开发语言·数据库·vue.js·spring boot·后端·旅游
Jane-66677712 小时前
C语言——表达式、语句、函数
c语言·开发语言·算法
arron889912 小时前
C# 项目源码进行全面的技术架构和调用逻辑分析。以下是系统性的技术方案
开发语言·架构·c#
88号技师12 小时前
【2025年1区SCI】最新信号分解方法-JMD的参数优化:15种适应度函数-matlab代码
开发语言·matlab·故障诊断·信号分解
zmzb010312 小时前
C++课后习题训练记录Day44
开发语言·c++
smile_Iris12 小时前
Day 30 函数定义与参数
开发语言·python
老华带你飞12 小时前
医院挂号|基于Java医院挂号管理系统(源码+数据库+文档)
java·开发语言·数据库·vue.js·spring boot