【设计模式】13、template 模板模式

news2024/11/16 18:11:01

文章目录

  • 十三、template 模板模式
    • 13.1 ppl
      • 13.1.1 目录层级
      • 13.1.2 ppl_test.go
      • 13.1.3 ppl.go
      • 13.1.4 llm_ppl.go
      • 13.1.5 ocr_ppl.go

十三、template 模板模式

https://refactoringguru.cn/design-patterns/template-method

如果是一套标准流程, 但有多种实现, 可以用 template 模板模式. 可以让父类定义整套流程, 子类实现各具体步骤. golang 中可通过 组合 interface 实现继承, 详见例子.

例如, 如果要开发一个数据挖掘程序, 支持输入 word, csv, pdf. 他们其实是相同的流程(如打开文件, 读取数据, 转换数据, 输出数据).

因为每种类别的流程相同, 所以每种类别的实现有很多重复代码.

为了消除这些重复代码, 可以定义基类, 实现通用的逻辑, 如果有个性化的逻辑再覆盖.

源码详见:godp/13template at master · datager/godp · GitHub

13.1 ppl

https://refactoringguru.cn/design-patterns/template-method/go/example

go 虽然没有继承, 但可通过 interface 和 组合实现. 框架如下:

type iTemplate interface {  
    step1()    
    step2()
}  

// 外部使用的基类  
type wrapper struct {  
    template iTemplate
}  

// 基类的方法: 串联整个流程  
func (w *wrapper) run() {  
    w.template.step1()    
    w.template.step2()
}  

然后有如下具体实现:

type impl1 struct {}  
func (i *impl1) step1() {}  
func (i *impl1) step2() {}  

type impl2 struct {}  
func (i *impl2) step1() {}  
func (i *impl2) step2() {}  

使用:

// 第一种实现  
w := &wrapper{template: &impl1{}}  
w.run()  

// 第二种实现  
w := &wrapper{template: &impl2{}}  
w.run()  

13.1.1 目录层级

├── llm_ppl.go
├── ocr_ppl.go
├── ppl.go
├── ppl_test.go
└── readme.md

13.1.2 ppl_test.go

package _31ppl

import (
	"fmt"
	"testing"
)

/*
=== RUN   TestLLMPipeline
llmPipeline 开始检测
llmPipeline 开始分类
llmPipeline 无需分割

ocrPipeline 开始检测
ocrPipeline 开始分类
ocrPipeline 需要分割
ocrPipeline 开始分割
--- PASS: TestLLMPipeline (0.00s)
PASS
*/
func TestLLMPipeline(t *testing.T) {
	e := &aiEngine{ppl: &llmPipeline{}}
	e.runPipeline()

	fmt.Println()
	e = &aiEngine{ppl: &ocrPipeline{}}
	e.runPipeline()
}

13.1.3 ppl.go

package _31ppl

// imagePipeline 图像处理流程
type imagePipeline interface {
	// 检测
	detect()
	// 分类
	classification()
	// 是否需要分割, 可影响父类的流程. 将它留给子类实现, 使子类的具体实现可影响父类的流程
	needSegmentation() bool
	// 分割
	segmentation()
}

type aiEngine struct {
	ppl imagePipeline
}

// go 通过组合, 对 interface 封装了一层, 封装的是 interface 的整个流程
func (e *aiEngine) runPipeline() {
	e.ppl.detect()
	e.ppl.classification()
	if e.ppl.needSegmentation() { // 父类的流程可能会变化, 取决于具体子类的实现
		e.ppl.segmentation()
	}
}

13.1.4 llm_ppl.go

package _31ppl

import "fmt"

type llmPipeline struct{}

func (ppl *llmPipeline) detect() {
	fmt.Println("llmPipeline 开始检测")
}

func (ppl *llmPipeline) classification() {
	fmt.Println("llmPipeline 开始分类")
}

func (ppl *llmPipeline) needSegmentation() bool {
	fmt.Println("llmPipeline 无需分割")
	return false
}

func (ppl *llmPipeline) segmentation() {
	panic("llmPipeline 无需分割, 流程错误!!!")
}

13.1.5 ocr_ppl.go

package _31ppl

import "fmt"

type ocrPipeline struct{}

func (ppl *ocrPipeline) detect() {
	fmt.Println("ocrPipeline 开始检测")
}

func (ppl *ocrPipeline) classification() {
	fmt.Println("ocrPipeline 开始分类")
}

func (ppl *ocrPipeline) needSegmentation() bool {
	fmt.Println("ocrPipeline 需要分割")
	return true
}

func (ppl *ocrPipeline) segmentation() {
	fmt.Println("ocrPipeline 开始分割")
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1643226.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

nodejs的ws+vue3编写聊天室的demo

nodejs编写ws服务是非常简单高效的,nodejs有众多的实现ws的库,如ws,SocketIO等,nodejs的事件线程是单线程的,所以不要在事件线程内做阻塞性的操作,耗时的操作交给工作线程或者子进程操作。 我使用nodejsvue3实现了写了…

安装vscode基础配置,es6基础语法,

https://code.visualstudio.com/ es6 定义变量 const声明常量(只读变量) // 1、声明之后不允许改变 const PI “3.1415926” PI 3 // TypeError: Assignment to constant variable. // 2、一但声明必须初始化,否则会报错 const MY_AGE /…

MySQL —— 表的基本操作

一、创建 1.语法 create table 表名称( 自定义变量1, 自定义变量2, 自定义变量3(最后一个变量末尾不需要加任何标点符号) )charset字符集 collate校验集 engine存储引擎; ps:若是不具体给字符集、校验集、储存引擎,则采用配置文件…

【网络安全产品】---应用防火墙(WAF)

what Web应用防火墙(Web Application Firewall) WAF可对网站或者App的业务流量进行恶意特征识别及防护,在对流量清洗和过滤后,将正常、安全的流量返回给服务器,避免网站服务器被恶意入侵导致性能异常等问题,从而保障…

计算机网络——Dijkstra路由算法

实验目的 实现基于 Dijkstra 算法的路由软件 实验内容 网络拓扑如图所示 实验过程 先编写开辟应该图的空间,然后给点映射数字,构建图。程序获取用户输入的学号,构建图中边的权值。接下来程序从用户输入获取最短路径的搜索起点&#xff0…

prometheus+grafana的安装与部署及优点

一、Prometheus 的优点 1、非常少的外部依赖,安装使用超简单; 2、已经有非常多的系统集成 例如:docker HAProxy Nginx JMX等等; 3、服务自动化发现; 4、直接集成到代码; 5、设计思想是按照分布式、微服…

QT Windows 实现调用Windows API获取ARP 表

简介 使用ping方式获取网络可访问或者存在的设备发现部分会无法ping通但实际网络上存在此设备, 但使用arp -a却可以显示出来, 所以现在使用windows API的方式获取arp 表。 实现 参考Windows提供的示例转化成Qt Qt .pro LIBS -liphlpapiLIBS -lws2_32…

分割链表

/*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/typedef struct ListNode ListNode; struct ListNode* partition(struct ListNode* head, int x){if(head NULL){return head;}//创建新链表ListNode* lessHead,*…

UE5(射线检测)学习笔记

这一篇会讲解射线检测点击事件、离开悬停、进入悬停事件的检测,以及关闭射线检测的事件,和射线检测蓝图的基础讲解。 创建一个简单的第三人称模板 创建一个射线检测的文件夹RadiationInspection,并且右键蓝图-场景组件-命名为BPC_Radiation…

用于密集预测任务的通道知识蒸馏——关键字:蒸馏

摘要 https://arxiv.org/pdf/2011.13256 知识蒸馏(KD)已被证明是训练紧凑密集预测模型的简单有效工具。通过从大型教师网络转移而来的额外监督来训练轻量级学生网络。大多数先前的针对密集预测任务的KD变体都在空间域中对学生网络和教师网络的激活图进行对齐,通常是通过在每…

pandas读取文件导致jupyter内核崩溃如何解决

读取execl文件出现以下问题: str_name "D:\\cao_use\\2017_2021(new).xlsx" train_df pd.read_excel(str_name, usecols[0])崩溃的指示图如下所示: bug原因:读入的文件太大,所需时间过长,在读取的过程中,使用中断按钮暂停会直…

C语言实战项目--贪吃蛇

贪吃蛇是久负盛名的游戏之一,它也和俄罗斯⽅块,扫雷等游戏位列经典游戏的行列。在编程语言的教学中,我们以贪吃蛇为例,从设计到代码实现来提升大家的编程能⼒和逻辑能⼒。 在本篇讲解中,我们会看到很多陌生的知识&…

13_Scala面向对象编程_伴生对象

文章目录 1.伴生对象1.1 scala的一个性质,scala文件中的类都是公共的;1.2 scala使用object关键字也可以声明对象; 3.关于伴生对象和类4.权限修饰符,scala仅有private;5.伴生对象可以访问伴生类中的私有属性;6.案例7.伴…

AI预测福彩3D第10套算法实战化赚米验证第1弹2024年5月5日第1次测试

从今天开始,准备启用第10套算法,来验证下本算法的可行性。因为本算法通过近三十期的内测(内测版没有公开预测结果),发现本算法的预测结果优于其他所有算法的效果。彩票预测只有实战才能检验是否有效,只有真…

【论文阅读】Sparse is Enough in Scaling Transformers

Sparse is Enough in Scaling Transformers 论文地址摘要1 介绍2 相关工作模型压缩。模型修剪模型蒸馏。稀疏注意力。张量分解。稀疏前馈。 3 Sparse is Enough3.1 稀疏前馈层3.2 稀疏 QKV 层3.3 稀疏损失层。 4 长序列的稀疏性4.1 长序列架构4.2 内存效率的可逆性4.3 泛化的循…

AI工具大揭秘:如何改变我们的工作和生活

文章目录 📑前言一、常用AI工具:便利与高效的结合1.1 语音助手1.2 智能推荐系统1.3 自然语言处理工具 二、创新AI应用:不断突破与发展2.1 医疗诊断AI2.2 智能家居2.3 无人驾驶技术 三、AI工具在人们生活中的应用和影响3.1 生活方式的变化3.2 …

Webshell绕过技巧分析之-base64/HEX/Reverse/Html/Inflate/Rot13

在网络安全运营,护网HVV,重保等活动的过程中,webshell是一个无法绕过的话题。通常出现的webshell都不是以明文的形式出现,而是针对webshell关键的内容进行混淆,编码来绕过网络安全产品(IDS,WAF&…

【深耕 Python】Quantum Computing 量子计算机(2)绘制电子运动平面波

写在前面 往期量子计算机博客: 【深耕 Python】Quantum Computing 量子计算机(1)图像绘制基础 一、所需公式 1、自由空间中电子的波函数公式: 2、常量代换: 3、物理常量: 二、Python代码: …

PostgreSQL和openGauss优化器对一个关联查询的SQL优化改写

PostgreSQL和openGauss数据库优化器在merge join关联查询的SQL优化改写 PostgreSQL 查询计划openGauss 查询计划拓展对比 看腻了文章就来听听视频讲解吧:https://www.bilibili.com/video/BV1oH4y137P7/ 数据库类型数据库版本PostgreSQL16.2openGauss6.0 创建测试表…

【Java基础】成员变量和局部变量的区别

成员变量vs局部变量 局部变量没有默认值 成员变量有默认值局部变量在栈中开辟内存 成员变量在堆中开辟内存局部变量是当其所在的函数被调用时开辟内存 成员变量是创建对象时开辟内存局部变量是当其作用域结束时立刻释放内存 成员变量是当其所属的对象成为垃圾时等待垃圾回收线…