快速了解 GO之接口解耦
更多个人笔记见:
(注意点击“继续”,而不是“发现新项目”)
github个人笔记仓库 https://github.com/ZHLOVEYY/IT_note
gitee 个人笔记仓库 https://gitee.com/harryhack/it_note
个人学习,学习过程中还会不断补充~ (后续会更新在github上)
文章目录
- 例子分析解耦
- 一般的构建思路
- 解耦的构建思路
接口解耦的作用是便于切换三方库(项目需要或者三方库废弃不维护)等时候,不用大量修改代码而构建的设计
例子分析解耦
xorm 和 gorm 如果希望互相切换,使用上区别在于二者创建数据库的方法不同,xorm 为 Insert,gorm 为 Create
一般的构建思路
构建 xorm 的:
type XormDB struct{db *xorm.Session...
}type Trade struct {*XormDB...
}func (t *Trade) InsertTrade( data interface{}) {t.db.Insert(data) ...
}
如果现在需要构建 gorm 的,就需要所有的替换成下面这样,同时接口等也都需要改变
type GormDB struct{db *Gorm.Session...
}type Trade struct {*GormDB...
}func (t *Trade) InsertTrade( data interface{}) error {t.db.Create(data) ...
}
解耦的构建思路
- 所以采用接口的方法:
//初始化 xorm
type DBer interface {Insert(ctx context.Context, instance interface{}) //定义统一的 insert方法
}type XormDB struct {db *xorm.Session
}
func (xorm *XormDB) Insert (ctx contesxt.COntext,instance ... interfaceP{}){xorm.db.Context(ctx).Insert(instance)
}//初始化 gorm
type GormDB struct {db *gorm.DB
}
func (gorm *GormDB) Insert(ctx context.Context,instance... interface{}){gorm.db.Context(ctx).Create(instance)
}//实际业务结构体
type Trade struct {db DBer
}
//初始化对应的数据库
func (t *Trade) AddDB(db DBer){t.db = db
}
//只要完成了 insert 方法就是可以的
func (t *Trade) AddTrade(ctx context.Context,instance interface{}){t.db.Insert(ctx,instance)
}
这样只用自己定义满足 DBer 接口的结构体,加入新的三方库就都是可以的,因为都是统一调用 Insert 方法
- 另外一个同样解耦构建的例子:
从底向上实现
// 定义数据访问层接口,这是一个统一的接口
type Repository interface {Create(entity interface{}) error//下面几个方法如果添加那么也要给GormRepository和XormRepository补上对应的 方法//FindByID(id uint, out interface{}) error//Update(entity interface{}) error//Delete(entity interface{}) error
}
注意:一般这几个不会放在同一个文件或者层次中的,比如model 层或者 dao 层等等,会在实际项目中划分开
// GORM实现
type GormRepository struct {db *gorm.DB
}func (r *GormRepository) Create(entity interface{}) error {return r.db.Create(entity).Error
}// XORM实现
type XormRepository struct {engine *xorm.Engine
}func (r *XormRepository) Create(entity interface{}) error {_, err := r.engine.Insert(entity)return err
}
具体业务逻辑:
// 业务层只依赖Repository接口
type UserService struct {repo Repository
}func NewUserService(repo Repository) *UserService {return &UserService{repo: repo} //初始化对应的实例
}func (s *UserService) CreateUser(user *User) error {return s.repo.Create(user) //调用接口对应的 Create 函数就可以了
}
初始化的时候决定具体的实现,使用自己定义的结构体,对应 gorm 的GormRepository还是对应 xorm 的XormRepository
所以除去结构体的修改和补充,其实只要在这个地方进行改动就可以了
//使用GORM
db := gorm.Open(...)
service := NewUserService(&GormRepository{db: db})//使用XORM
engine, _ := xorm.NewEngine(...)
service := NewUserService(&XormRepository{engine: engine})
(补充)工厂模式切换:
func NewRepository(dbType string, conn interface{}) (Repository, error) {switch dbType {case "gorm":return &GormRepository{db: conn.(*gorm.DB)}, nilcase "xorm":return &XormRepository{engine: conn.(*xorm.Engine)}, nildefault:return nil, errors.New("unsupported database type")}
}
解耦的好处:
- 切换ORM(例子中是 ORM)只需修改初始化代码
- 易于单元测试(mock Repository)
- 不一定固定依赖某个三方库
相关文章:
快速了解 GO之接口解耦
更多个人笔记见: (注意点击“继续”,而不是“发现新项目”) github个人笔记仓库 https://github.com/ZHLOVEYY/IT_note gitee 个人笔记仓库 https://gitee.com/harryhack/it_note 个人学习,学习过程中还会不断补充&…...

【多线程初阶】内存可见性问题 volatile
文章目录 再谈线程安全问题内存可见性问题可见性问题案例编译器优化 volatileJava内存模型(JMM) 再谈线程安全问题 如果多线程环境下代码运行的结果是符合我们预期的,即在单线程环境应该有的结果,则说这个程序是线程安全的,反之,多线程环境中,并发执行后,产生bug就是线程不安全…...

C++ 类模板三参数深度解析:从链表迭代器看类型推导与实例化(为什么迭代器类模版使用三参数?实例化又会是怎样?)
本篇主要续上一篇的list模拟实现遇到的问题详细讲解:<传送门> 一、引言:模板参数的 "三角锁钥" 在 C 双向链表实现中,__list_iterator类模板的三个参数(T、Ref、Ptr)如同精密仪器的调节旋钮&#x…...

MySQL强化关键_018_MySQL 优化手段及性能分析工具
目 录 一、优化手段 二、SQL 性能分析工具 1.查看数据库整体情况 (1)语法格式 (2)说明 2.慢查询日志 (1)说明 (2)开启慢查询日志功能 (3)实例 3.s…...

ASP.NET MVC添加模型示例
ASP.NET MVC高效构建Web应用ASP.NET MVC 我们总在谈“模型”,那到底什么是模型?简单说来,模型就是当我们使用软件去解决真实世界中各种实际问题的时候,对那些我们关心的实际事物的抽象和简化。比如,我们在软件系统中设…...

【Part 3 Unity VR眼镜端播放器开发与优化】第二节|VR眼镜端的开发适配与交互设计
文章目录 《VR 360全景视频开发》专栏Part 3|Unity VR眼镜端播放器开发与优化第一节|基于Unity的360全景视频播放实现方案第二节|VR眼镜端的开发适配与交互设计一、Unity XR开发环境与设备适配1.1 启用XR Plugin Management1.2 配置OpenXR与平…...

第1天:认识RNN及RNN初步实验(预测下一个数字)
RNN(循环神经网络) 是一种专门设计用来处理序列数据的人工神经网络。它的核心思想是能够“记住”之前处理过的信息,并将其用于当前的计算,这使得它非常适合处理具有时间顺序或上下文依赖关系的数据。 核心概念:循环连…...
全文索引详解及适用场景分析
全文索引详解及适用场景分析 1. 全文索引基本概念 1.1 定义与核心原理 全文索引(Full-Text Index)是一种特殊的数据库索引类型,专门设计用于高效处理文本数据的搜索需求。与传统的B树索引不同,全文索引不是基于精确匹配,而是通过建立倒排索引(Inverted Index)结构来实现对…...
利用DeepSeek编写能在DuckDB中读PostgreSQL表的表函数
前文实现了UDF和UDAF,还有一类函数是表函数,它放在From 子句中,返回一个集合。DuckDB中已有PostgreSQL插件,但我们可以用pqxx库实现一个简易的只读read_pg()表函数。 提示词如下: 请将libpqxx库集成到我们的程序&#…...

树莓派安装openwrt搭建软路由(ImmortalWrt固件方案)
🤣👉我这里准备了两个版本的openwrt安装方案给大家参考使用,分别是原版的OpenWrt固件以及在原版基础上进行改进的ImmortalWrt固件。推荐使用ImmortalWrt固件,当然如果想直接在原版上进行开发也可以,看个人选择。 &…...
排序算法——详解
排序算法 (冒泡、选择、插入、快排、归并、堆排、计数、桶、基数) 稳定性 (Stability): 如果排序算法能保证,当待排序序列中存在值相等的元素时,排序后这些元素的相对次序保持不变,那么该算法就是稳定的。 例如&#…...
Go整合Redis2.0发布订阅
Go整合Redis2.0发布订阅 Redis goredis-cli --version redis-cli 5.0.14.1 (git:ec77f72d)Go go get github.com/go-redis/redis/v8package redisimport ("MyKindom-Server-v2.0/com/xzm/core/config/yaml""MyKindom-Server-v2.0/com/xzm/core/config/yaml/po…...

电子电气架构 --- 如何应对未来区域式电子电气(E/E)架构的挑战?
我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 做到欲望极简,了解自己的真实欲望,不受外在潮流的影响,不盲从,不跟风。把自己的精力全部用在自己。一是去掉多余,凡事找规律,基础是诚信;二是…...
鸿蒙OS基于UniApp的区块链钱包开发实践:打造支持鸿蒙生态的Web3应用#三方框架 #Uniapp
基于UniApp的区块链钱包开发实践:打造支持鸿蒙生态的Web3应用 前言 最近在带领团队开发一个支持多链的区块链钱包项目时,我们选择了UniApp作为开发框架。这个选择让我们不仅实现了传统移动平台的覆盖,还成功将应用引入了快速发展的鸿蒙生态…...

易学探索助手-个人记录(十二)
近期我完成了古籍处理板块页面升级,补充完成原文、句读、翻译的清空、保存和编辑(其中句读仅可修改标点)功能,新增原文和句读的繁简体切换功能 一、古籍处理板块整体页面升级 将原来一整个页面呈现的布局改为分栏呈现࿰…...
Windows 账号管理与安全指南
Windows 账号管理与安全指南 概述 Windows 账号管理是系统安全的基础,了解如何正确创建、管理和保护用户账户对于系统管理员和安全专业人员至关重要。本文详细介绍 Windows 系统中的账户管理命令、隐藏账户创建方法以及安全防护措施。 基础账户管理命令 net use…...

Python窗体编程技术详解
文章目录 1. Tkinter简介示例代码优势劣势 2. PyQt/PySide简介示例代码(PyQt5)优势劣势 3. wxPython简介示例代码优势劣势 4. Kivy简介示例代码优势劣势 5. PySimpleGUI简介示例代码优势劣势 技术对比总结选择建议 Python提供了多种实现图形用户界面(GUI)编程的技术,…...
思维链提示:激发大语言模型推理能力的突破性方法
论文出处: Chain-of-Thought Prompting Elicits Reasoning in Large Language Models 作者: Jason Wei, Xuezhi Wang, Dale Schuurmans, Maarten Bosma, Brian Ichter, Fei Xia, Ed H. Chi, Quoc V. Le, Denny Zhou 机构: Google Research, B…...

NVMe协议简介之AXI总线更新
更新AXI4总线知识 AXI4总线协议 AXI4总线协议是由ARM公司提出的一种片内总线协议 ,旨在实现SOC中各模块之间的高效可靠的数据传输和管理。AXI4协议具有高性能、高吞吐量和低延迟等优点,在SOC设计中被广泛应用 。随着时间的推移,AXI4的影响不…...

设计模式——责任链设计模式(行为型)
摘要 责任链设计模式是一种行为型设计模式,旨在将请求的发送者与接收者解耦,通过多个处理器对象按链式结构依次处理请求,直到某个处理器处理为止。它包含抽象处理者、具体处理者和客户端等核心角色。该模式适用于多个对象可能处理请求的场景…...

基于Android的医院陪诊预约系统
博主介绍:java高级开发,从事互联网行业六年,熟悉各种主流语言,精通java、python、php、爬虫、web开发,已经做了六年的毕业设计程序开发,开发过上千套毕业设计程序,没有什么华丽的语言࿰…...

基于Spring Boot 电商书城平台系统设计与实现(源码+文档+部署讲解)
技术范围:SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:免费功能设计、开题报告、任务书、中期检查PPT、系统功能实现、代码编写、论文编写和辅导、论文…...

【金融基础学习】债券回购方式
债券回购作为货币市场的重要工具,本质上是一种以债券为抵押的短期资金借贷行为。在银行间市场,质押式回购与**买断式回购*是两种主要形式。 1. 质押式回购(Pledged Repo, RP) – 所有权不转移的短期融资工具 1.1 质押式回购概述 质押式回购是交易双方…...

第五十九节:性能优化-GPU加速 (CUDA 模块)
在计算机视觉领域,实时性往往是关键瓶颈。当传统CPU处理高分辨率视频流或复杂算法时,力不从心。本文将深入探索OpenCV的CUDA模块,揭示如何通过GPU并行计算实现数量级的性能飞跃。 一、GPU加速:计算机视觉的必由之路 CPU的强项在于复杂逻辑和低延迟任务,但面对图像处理中高…...

单元测试-概述入门
目录 main方法测试缺点: 在pom.xm中,引入junit的依赖。,在test/java目录下,创建测试类,并编写对应的测试方法,并在方法上声明test注解。 练习:验证身份证合法性 测试成功 测试失败 main方法测试缺点&am…...

⚡ Hyperlane —— 比 Rocket 更快的 Rust Web 框架!
⚡ Hyperlane —— 比 Rocket 更快的 Rust Web 框架! 在现代 Web 服务开发中,开发者需要一个既轻量级又高性能的 HTTP 服务器库来简化开发流程,同时确保服务的高效运行。Hyperlane 正是为此而生——一个专为 Rust 开发者设计的 HTTP 服务器库…...

《AI Agent项目开发实战》DeepSeek R1模型蒸馏入门实战
一、模型蒸馏环境部署 注:本次实验仍然采用Ubuntu操作系统,基本配置如下: 需要注意的是,本次公开课以Qwen 1.5-instruct模型为例进行蒸馏,从而能省略冷启动SFT过程,并且 由于Qwen系列模型本身性能较强&…...
Ubuntu 24.04 LTS Chrome 中文输入法(搜狗等)失效?一行命令解决
Ubuntu 24.04 LTS Chrome 中文输入法(搜狗等)失效?一行命令解决 在 Ubuntu 24.04 LTS 中,如果你发现 Chrome 浏览器用不了搜狗输入法或其他 Fcitx5 中文输入法,可以试试下面的方法。 直接上解决方案: 打…...

字节golang后端二面
前端接口使用restful格式,post与get的区别是什么? HTTP网络返回的状态码有哪些? go语言切片与数组的区别是什么? MySQL实现并发安全避免两个事务同时对一个记录写操作的手段有哪些? 如何实现业务的幂等性(在…...
计算机网络物理层基础练习
第二章 物理层 填空题 从通信双方信息交互的方式来看,通信的三种基本方式为单工、半双工和全双工。其中,单工数据传输只支持数据在一个方向上传输,全双工数据传输则允许数据同时在两个方向上传输。最基本的带通调制方法包括三种:…...