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


    第 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 main
    
    import (
    	"context"
    	"errors"
    )
    
    // CrudInterface 定义了CRUD操作的方法
    type CrudInterface interface {
    	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
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    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
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    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
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    3.4 创建存储的工厂函数

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

    func NewCrudStore(uri string) (CrudInterface, error) {
    	switch uri {
    	case "mysql://default":
    		return &MySQLStore{}, nil
    	case "redis://default":
    		return &RedisStore{}, nil
    	default:
    		return nil, errors.New("unsupported URI scheme")
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    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")
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    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 作为后端存储,而不需要修改业务逻辑代码。这种设计提高了系统的可扩展性和可维护性。

  • 相关阅读:
    ComPDFKit PDF SDK Crack
    基于 SpringBoot + Vue 的在线课堂前后端分离项目
    路由传参的方式
    Xcode报错“compact unwind compressed function offset doesn‘t fit in 24 bits
    Verilog编写VGA控制器
    即时通讯开发如何撸一个WebSocket服务器
    10 个解放双手的 IDEA插件,少些冤枉代码(第三弹)
    华为机试真题 Java 实现【补种未成活胡杨】
    CentOS Nginx crontab 定时执行PHP代码命令任务(tp5.1 tp6 EasyTask) 每天重启执行PHP自定义命令
    如何利用Web应用防火墙应对未知威胁
  • 原文地址:https://blog.csdn.net/Mandel19/article/details/138142829