当前位置: 首页 > article >正文

golang 泛型 middleware 设计模式: 一次只做一件事

golang 泛型 middleware 设计模式: 一次只做一件事

1. 前言

本文主要介绍 在使用 gRPC 和 Gin 框架中常用的 middleware 设计模式

还有几种叫法

  1. 装饰器模式
  2. Pipeline 模式

设计思想:

  1. 10 个 10 行函数, 而不是 1 个 100 行函数
  2. 一次只做一件事, 而不一次做多件事
  3. 单一职责

2. 代码

已生产环境中大量使用, 每日执行千万次

package chain

type Ctx[T any] struct {
	in  T // 数据入参
	fns []func(c *Ctx[T], in T) (err error)
	idx int
}

func NewCtx[T any](in T) *Ctx[T] {
	return &Ctx[T]{
		in:  in,
		idx: -1,
	}
}

func (c *Ctx[T]) Next() (err error) {
	c.idx++
	for ; c.idx < len(c.fns); c.idx++ {
		err = c.fns[c.idx](c, c.in)
		if err != nil {
			return
		}
	}
	return
}

func (c *Ctx[T]) Add(fns ...func(c *Ctx[T], in T) (err error)) {
	c.fns = append(c.fns, fns...)
}

3. test case

package chain

import (
	"fmt"
	"testing"
	"time"
)

type Input struct {
	a int
}

func TestNewCtx(t *testing.T) {

	// 初始化
	in := Input{a: 1}
	c := NewCtx(&in)

	// 添加中间件
	c.Add(ctx1_cost)    // 记录耗时
	c.Add(ctx2_add)     // 数据加工
	c.Add(ctx3_product) // 数据加工2

	// 执行
	err := c.Next()
	if err != nil {
		panic(err)
	}

	// 检查结果
	fmt.Println(in.a)
	if in.a != 4 {
		panic(fmt.Sprintf("expect 4, but got %d", in.a))
	}
}

func ctx1_cost(c *Ctx[*Input], in *Input) (err error) {
	start := time.Now()
	defer func() {
		cost := time.Since(start)
		fmt.Println("cost:", cost)
	}()

	err = c.Next()
	return
}

func ctx2_add(c *Ctx[*Input], in *Input) (err error) {
	in.a += 1
	return
}

func ctx3_product(c *Ctx[*Input], in *Input) (err error) {
	in.a *= 2
	return
}


http://www.kler.cn/a/391728.html

相关文章:

  • 更改Ubuntu22.04锁屏壁纸
  • 【QT】QSS
  • 一种基于深度学习的反无人机无人值守系统及方法
  • 多叉树笔记
  • scrapy爬取中信证券销售金融产品信息
  • PostgreSQL 开启密码验证插件
  • (已解决)Java不是内部或者外部命令,也不是可运行的程序
  • 工位管理新纪元:Spring Boot企业系统
  • Chrome使用IE内核
  • SCUI Admin + Laravel 整合
  • 网络安全-蓝队基础
  • 科学计算服务器:如何计算算力?如何提升科学研究效率?
  • 音视频入门基础:MPEG2-TS专题(4)——使用工具分析MPEG2-TS传输流
  • Python、selenium 自动化 - 实现自动上传外部文件
  • Flutter 小技巧之 OverlayPortal 实现自限性和可共享的页面图层
  • 设计模式(四)装饰器模式
  • RHEL 网络配置(Linux网络服务器 09)
  • ubuntu20.04安装anaconda与基本使用
  • 黑马程序员Docker学习【持续更新】
  • 电子商务网站之首页设计
  • 【论文解读CVPR2024】Scaffold-GS: Structured 3D Gaussians for View-Adaptive Rendering
  • 【JavaEE进阶】Spring 事务和事务传播机制
  • 《硬件架构的艺术》笔记(二):时钟与复位
  • DAY6 线程
  • 情绪如何影响用户体验?
  • Unity 插件 - Project窗口资源大小显示