【Golang】数据设计模式

在Go语言中,根据不同业务类型返回不同表数据,可以使用以下几种方式来设计方法的出参:

1. 使用接口(interface)作为返回类型

go 复制代码
// 定义一个通用的业务数据接口
type BusinessData interface {
    GetId() int64
    GetName() string
}

// 不同业务类型实现该接口
type SampleData struct {
    Id   int64  `json:"id"`
    Name string `json:"name"`
    // 其他样本特有字段
}

func (s SampleData) GetId() int64 { return s.Id }
func (s SampleData) GetName() string { return s.Name }

type ProjectData struct {
    Id   int64  `json:"id"`
    Name string `json:"name"`
    // 其他项目特有字段
}

func (p ProjectData) GetId() int64 { return p.Id }
func (p ProjectData) GetName() string { return p.Name }

// 业务处理方法
func GetBusinessData(businessType string, id int64) (BusinessData, error) {
    switch businessType {
    case "sample":
        // 查询样本数据
        var data SampleData
        // ... 查询逻辑
        return data, nil
    case "project":
        // 查询项目数据
        var data ProjectData
        // ... 查询逻辑
        return data, nil
    default:
        return nil, errors.New("unsupported business type")
    }
}

2. 使用泛型(Go 1.18+)

go 复制代码
// 定义泛型方法
func GetBusinessData[T SampleData|ProjectData](businessType string, id int64) (T, error) {
    var result T
    switch businessType {
    case "sample":
        if t, ok := any(result).(SampleData); ok {
            // 查询样本数据逻辑
            // ...
            result = any(t).(T)
        }
    case "project":
        if t, ok := any(result).(ProjectData); ok {
            // 查询项目数据逻辑
            // ...
            result = any(t).(T)
        }
    }
    return result, nil
}

3. 使用any/interface{} + 类型断言

go 复制代码
func GetBusinessData(businessType string, id int64) (interface{}, error) {
    switch businessType {
    case "sample":
        var data SampleData
        // 查询样本数据逻辑
        // ...
        return data, nil
    case "project":
        var data ProjectData
        // 查询项目数据逻辑
        // ...
        return data, nil
    default:
        return nil, errors.New("unsupported business type")
    }
}

// 使用时进行类型断言
func Usage() {
    data, err := GetBusinessData("sample", 1)
    if err != nil {
        // 处理错误
        return
    }
    
    switch v := data.(type) {
    case SampleData:
        // 处理样本数据
        fmt.Println("Sample:", v.Name)
    case ProjectData:
        // 处理项目数据
        fmt.Println("Project:", v.Name)
    }
}

4. 使用统一的响应结构体

go 复制代码
type BusinessResponse struct {
    BusinessType string      `json:"businessType"`
    Data         interface{} `json:"data"`
}

func GetBusinessData(businessType string, id int64) (*BusinessResponse, error) {
    resp := &BusinessResponse{
        BusinessType: businessType,
    }
    
    switch businessType {
    case "sample":
        var data SampleData
        // 查询样本数据逻辑
        // ...
        resp.Data = data
    case "project":
        var data ProjectData
        // 查询项目数据逻辑
        // ...
        resp.Data = data
    default:
        return nil, errors.New("unsupported business type")
    }
    
    return resp, nil
}

5. 在你的具体场景中应用

根据你提供的代码,可以这样设计:

go 复制代码
// 定义业务审批数据接口
type BusinessApprovalData interface {
    GetId() int64
    GetBusinessId() int64
    GetStatus() int
}

// 样本审批数据
type SampleApprovalData struct {
    Id         int64  `json:"id"`
    BusinessId int64  `json:"businessId"`
    SampleName string `json:"sampleName"`
    Status     int    `json:"status"`
}

func (s SampleApprovalData) GetId() int64 { return s.Id }
func (s SampleApprovalData) GetBusinessId() int64 { return s.BusinessId }
func (s SampleApprovalData) GetStatus() int { return s.Status }

// 项目审批数据
type ProjectApprovalData struct {
    Id         int64  `json:"id"`
    BusinessId int64  `json:"businessId"`
    ProjectName string `json:"projectName"`
    Status     int    `json:"status"`
}

func (p ProjectApprovalData) GetId() int64 { return p.Id }
func (p ProjectApprovalData) GetBusinessId() int64 { return p.BusinessId }
func (p ProjectApprovalData) GetStatus() int { return p.Status }

// 修改你的方法
func (c *cUserTask) ToDoTaskList(ctx context.Context, req *usertask.UserTaskListInp) (interface{}, error) {
    instanceIdList, err := c.ToDoTaskInstanceIdList(ctx)
    if err != nil {
        return nil, err
    }
    
    if req.BusinessType == "" {
        return nil, nil
    }
    
    inp := bizin.WorkflowModelInstanceByConditionInp{
        FlwInstantIdList: instanceIdList, 
        BusinessType: req.BusinessType,
    }
    
    instanceList, err := service.BizWorkflowModelInstance().ListByCondition(ctx, &inp)
    if err != nil {
        return nil, err
    }
    
    businessIdList := make([]int64, 0, len(instanceList))
    for _, each := range instanceList {
        businessIdList = append(businessIdList, each.BusinessId)
    }
    
    // 根据业务类型返回不同数据
    switch req.BusinessType {
    case "sample":
        // 获取样本审批数据
        var approvalDataList []SampleApprovalData
        // ... 查询逻辑
        return approvalDataList, nil
    case "project":
        // 获取项目审批数据
        var approvalDataList []ProjectApprovalData
        // ... 查询逻辑
        return approvalDataList, nil
    default:
        return nil, errors.New("unsupported business type")
    }
}

推荐使用第1种或第4种方式,它们既保持了类型安全,又具有良好的可读性和可维护性。

相关推荐
nice_lcj5204 小时前
ThreadLocal 入门:它是怎么隔离数据的、为什么会导致内存泄漏
java·开发语言·后端·面试·并发编程·内存泄漏·threadlocal
紧跟先前的步伐4 小时前
Go AI Agent 实战 28|Agent 的预算、超时与停止条件
开发语言·人工智能·后端·ai·golang
bksczm5 小时前
InnoDB 行格式详解:DYNAMIC / COMPACT / COMPRESSED / REDUNDANT
java·开发语言·数据库
春涧草茶5 小时前
慢就是快16-1协程
开发语言·前端·python
Dovis(誓平步青云)6 小时前
启元 T1 Pro 人机相声搭档:语音-触摸双通道的启元机器人节奏引擎设计
开发语言·前端·javascript·microsoft·交互
做科研的周师兄6 小时前
【R语言实战】MixSIAR 氢氧同位素水源解析全流程:从混合空间校验到贝叶斯 MCMC 收敛诊断(后附完整代码)
java·大数据·开发语言
.痞老板.7 小时前
java ee--计算机是如何工作的
java·开发语言·java-ee
奇树谦7 小时前
Qt Quick 图片加载与 GPU 纹理机制详解:QImage、QQuickTextureFactory、QSGTexture 与异步加载
开发语言·qt·系统架构
青梅味猪大肠8 小时前
【操作系统-60】临近适应算法
java·linux·开发语言·嵌入式硬件·算法·操作系统
starzy19909 小时前
深入理解Scala可变Map:动态构建场景下的性能与设计权衡
开发语言·scala