第 3 章:GO 的接口和抽象 拓展篇 - CRUD 接口实现示例

ops/2025/3/4 14:54:56/

第 3 章:GO 的接口和抽象 拓展篇 - CRUD 接口实现示例

在前面的第3章中,我们用简单的代码展示了GO的接口和抽象方法,但是代码的示例较少,部分同学可能会觉得理解起来比较抽象。因此在本章中,我们将通过一个具体的例子来演示如何使用 GO 语言的接口来实现抽象化的设计。我们将定义一个 CrudInterface 接口,该接口将提供 CRUD(创建、读取、更新、删除)操作的通用方法。然后,我们将为两种不同的存储系统(MySQL 和 Redis)提供该接口的具体实现。此外,我们还将展示如何根据传入参数中的 URI 协议来动态选择使用哪种存储实现。

Implements
Implements
CrudInterface
+Create(ctx context.Context, key string, value interface) : error
+Read(ctx context.Context, key string) (interface, error)
+Update(ctx context.Context, key string, value interface) : error
+Delete(ctx context.Context, key string) : error
MySQLStore
+Create(ctx context.Context, key string, value interface) : error
+Read(ctx context.Context, key string) (interface, error)
+Update(ctx context.Context, key string, value interface) : error
+Delete(ctx context.Context, key string) : error
RedisStore
+Create(ctx context.Context, key string, value interface) : error
+Read(ctx context.Context, key string) (interface, error)
+Update(ctx context.Context, key string, value interface) : error
+Delete(ctx context.Context, key string) : error
3.1 定义 CrudInterface 接口

首先,我们定义 CrudInterface 接口,它包含 CRUD 操作的方法:

package mainimport ("context""errors"
)// CrudInterface 定义了CRUD操作的方法
type CrudInterface interface {Create(ctx context.Context, key string, value interface{}) errorRead(ctx context.Context, key string) (interface{}, error)Update(ctx context.Context, key string, value interface{}) errorDelete(ctx context.Context, key string) error
}
3.2 实现 MySQL 存储

我们将创建一个 MySQLStore 结构体,它实现了 CrudInterface 接口:

type MySQLStore struct {// 此处包含连接数据库所需的字段
}func (m *MySQLStore) Create(ctx context.Context, key string, value interface{}) error {// 实现创建逻辑return nil
}func (m *MySQLStore) Read(ctx context.Context, key string) (interface{}, error) {// 实现读取逻辑return nil, nil
}func (m *MySQLStore) Update(ctx context.Context, key string, value interface{}) error {// 实现更新逻辑return nil
}func (m *MySQLStore) Delete(ctx context.Context, key string) error {// 实现删除逻辑return nil
}
3.3 实现 Redis 存储

同样地,我们将创建一个 RedisStore 结构体,它也实现了 CrudInterface 接口:

type RedisStore struct {// 此处包含连接Redis所需的字段
}func (r *RedisStore) Create(ctx context.Context, key string, value interface{}) error {// 实现创建逻辑return nil
}func (r *RedisStore) Read(ctx context.Context, key string) (interface{}, error) {// 实现读取逻辑return nil, nil
}func (r *RedisStore) Update(ctx context.Context, key string, value interface{}) error {// 实现更新逻辑return nil
}func (r *RedisStore) Delete(ctx context.Context, key string) error {// 实现删除逻辑return nil
}
3.4 创建存储的工厂函数

我们将编写一个工厂函数 NewCrudStore,它根据 URI 协议来创建和返回相应的 CrudInterface 实现:

func NewCrudStore(uri string) (CrudInterface, error) {switch uri {case "mysql://default":return &MySQLStore{}, nilcase "redis://default":return &RedisStore{}, nildefault:return nil, errors.New("unsupported URI scheme")}
}
3.5 主程序中的动态选择

在主程序中,我们将使用传入的 URI 参数来动态选择和创建存储实现:

func main() {uri := "mysql://default" // 这可以是命令行参数或其他配置来源store, err := NewCrudStore(uri)if err != nil {log.Fatalf("Failed to create CRUD store: %v", err)}// 现在可以使用store进行CRUD操作// 例如: store.Create(ctx, "key", "value")
}
3.6 用时序图来描述一种可能的行为

基于上面的代码,我们可以得出一种可能的行为,当客户端要创建一条记录时,NewCrudStore能过传入的URL参数,得知这次的创建是要写入redis,于是最终接口调用了RedisStore保存了数据。

客户端 main函数 NewCrudStore工厂函数 RedisStore Redis数据库 调用创建记录 创建CrudInterface实例 传入URI参数 "redis://default" 实例化RedisStore 连接到Redis 连接成功 返回RedisStore实例 调用Create方法 执行SET命令 返回执行结果 返回结果给main函数 返回结果给客户端 客户端 main函数 NewCrudStore工厂函数 RedisStore Redis数据库

在这个时序图中:

  1. 客户端调用main函数来创建一条新记录。
  2. main函数请求NewCrudStore工厂函数创建一个CrudInterface类型的实例。
  3. NewCrudStore工厂函数根据传入的URI参数(在这个场景中是"redis://default")实例化一个RedisStore对象。
  4. RedisStore对象尝试连接到Redis数据库。
  5. 连接成功后,RedisStoreCreate方法被main函数调用,以创建新记录。
  6. RedisStore在Redis数据库中执行SET命令来保存新记录。
  7. Redis数据库返回执行结果给RedisStore
  8. RedisStore将结果返回给main函数。
  9. 最终,main函数将结果返回给客户端。

通过这个例子,我们展示了如何利用 GO 语言的接口特性来实现一个灵活的、可插拔的 CRUD 服务。程序可以根据运行时的配置动态选择使用 MySQL 或 Redis 作为后端存储,而不需要修改业务逻辑代码。这种设计提高了系统的可扩展性和可维护性。


http://www.ppmy.cn/ops/15674.html

相关文章

(三)组合特征与特征变换 学习简要笔记 #机器学习特征工程 #CDA学习打卡

目录 一. 统计及组合特征 1)统计特征 2)业务特征 3)组合特征 (a)简单组合特征 (b)模型特征组合 二. 特征变换 1)对数变换(Logarithmic Transformation&#xff0…

vue3的getCurrentInstance获取当前组件实例

vue3的setup中没有this时需要使用getCurrentInstance()来获取。 在 Vue 3 中,getCurrentInstance 方法可以在组合式 API(Composition API)中获取当前组件实例。这个方法返回一个包含了组件实例的对象,你可以用它来访问组件的 pro…

vue3第二十四节(JSX用法)

vite 创建项目的情况下 安装 npm i vitejs/plugin-vue-jsx -D配置vite.config.js import { defineConfig } from vite import vue from vitejs/plugin-vue import vueJsx from vitejs/plugin-vue-jsx // https://vitejs.dev/config/ export default defineConfig({plugins: […

如何批量跟踪京东物流信息

随着电商行业的快速发展,快递业务日益繁忙,无论是商家还是消费者,都需要一种高效、便捷的快递查询工具。快递批量查询高手软件应运而生,以其强大的功能和便捷的操作体验,赢得了广大电商、微商精英们的青睐。 快递批量…

WebRTC初识

1. 概念 WebRTC (Web-Real-Time Communications) 是一项实时的通讯及技术,它允许网络应用或站点在不借助中间媒介的情况下,建立浏览器之间点对点(Peer-to-Peer)的连接,实现视频流、音频流或其他任意数据的传输。这种技…

CSS画一条虚线,并且灵活设置虚线的宽度和虚线之间的间隔和虚线的颜色

CSS画一条虚线,并且灵活设置虚线的宽度和虚线之间的间隔和虚线的颜色。 先看效果图: 在CSS中,你可以使用border属性或者background属性来画一条虚线。以下是两种常见的方法: 方法一:使用border属性 你可以设置一个元素的border…

SpringCloud系列(15)--Eureka自我保护

前言:在上一章节中我们说明了一些关于Eureka的服务发现功能,也用这个功能进行接口的实现,在本章节则介绍一些关于Eureka的自我保护 1、Eureka保护模式概述 保护模式主要用于一组客户端和Eureka Server之间存在网络分区场景下的保护。默认情况…

Pow(x,n)——力扣

python(快速幂) 50. Pow(x, n) 已解答 中等 相关标签 相关企业 实现 pow(x, n) ,即计算 x 的整数 n 次幂函数(即,xn )。 示例 1: 输入:x 2.00000, n 10 输出:10…