Private
Public Access
1
0
Files
u-desk/docs/04-功能迭代/GO-DESK-2.数据库客户端/知识库/规范/架构规范.md

9.0 KiB
Raw Blame History

架构规范

状态:已确定
最后更新2025-01-28


一、后端架构规范

1.1 分层架构

API层 (internal/api/)
  ↓
Service层 (internal/service/)
  ↓
Repository层 (internal/storage/repository/)
  ↓
Infrastructure层 (internal/dbclient/)

1.2 职责划分

API层

  • 职责:暴露给前端的接口
  • 约束只负责参数验证和调用Service
  • 文件命名{功能}_api.go

Service层

  • 职责:业务逻辑处理
  • 约束不直接访问数据库通过Repository
  • 文件命名{功能}_service.go

Repository层

  • 职责:数据访问
  • 约束只负责CRUD操作不包含业务逻辑
  • 文件命名{模型}_repo.go

Infrastructure层

  • 职责:基础设施(数据库客户端、连接池等)
  • 约束:提供统一的接口,隐藏实现细节

二、前端架构规范

2.1 组件结构

Views (views/db-cli/)
  ↓
Components (components/)
  ↓
Composables (composables/)
  ↓
Types (types/)

2.2 职责划分

Views

  • 职责:页面级组件,负责布局和状态协调
  • 约束:不包含具体业务逻辑

Components

  • 职责:可复用组件
  • 约束组件应该是无状态的通过props接收数据

Composables

  • 职责:状态管理和业务逻辑
  • 约束:可复用的逻辑封装

Types

  • 职责TypeScript类型定义
  • 约束:所有类型定义集中管理

三、事件系统规范

3.1 事件命名

  • 格式<组件>-<动作><功能>-<动作>
  • 示例connection-selecttable-structure

3.2 事件参数

  • 格式:对象格式,不使用多个参数
  • 类型所有事件都有TypeScript类型定义
  • 位置types/events.ts

3.3 事件处理

  • 位置:在父组件中处理
  • 职责调用相应的composable方法

四、架构设计美学原则

4.1 参数数量约束(最高优先级)

原则:方法参数不得超过 3 个,超过必须使用结构体/对象封装。

违反示例(不可接受):

// ❌ 9个参数完全不可接受
func SaveDbConnection(id uint, name, dbType, host string, port int, username, password, database, options string) error

正确示例

// ✅ 使用结构体封装
type SaveConnectionRequest struct {
    ID       uint
    Name     string
    Type     string
    Host     string
    Port     int
    Username string
    Password string
    Database string
    Options  string
}
func SaveDbConnection(req SaveConnectionRequest) error

前端同理

// ❌ 参数过多
function saveConnection(id: number, name: string, type: string, host: string, port: number, username: string, password: string, database: string, options: string)

// ✅ 使用对象封装
interface SaveConnectionRequest {
  id: number
  name: string
  type: string
  host: string
  port: number
  username: string
  password: string
  database: string
  options: string
}
function saveConnection(req: SaveConnectionRequest)

4.2 依赖注入美学

原则:减少手动依赖注入,优先使用自动依赖获取。

当前问题

// 需要手动注入依赖
const { executeSQL } = useSqlExecution(resultState, messageLog)

优化方向

// 内部自动获取依赖(通过 provide/inject 或全局状态)
const { executeSQL } = useSqlExecution()

4.3 代码简洁性

原则:代码应该简洁、直接、易于理解。

要求

  • 避免过度抽象
  • 减少中间层
  • 直接表达意图
  • 移除不必要的包装

4.4 一致性原则

原则:相同功能在不同实现中保持一致的命名和结构。

要求

  • 统一的错误处理方式
  • 统一的命名规范
  • 统一的数据结构
  • 统一的接口风格

4.5 可组合性

原则Composables 应该可以独立使用,也可以组合使用。

要求

  • Composables 之间依赖关系清晰
  • 支持按需组合
  • 避免循环依赖
  • 提供清晰的组合模式

五、架构优化建议

5.1 后端 API 层优化(高优先级)

问题API 方法参数过多,违反设计美学。

优化方案

  1. 所有 API 方法参数超过 3 个时,必须使用请求结构体
  2. 统一请求/响应结构体命名:{Action}Request / {Action}Response
  3. 结构体定义放在对应的 API 文件中

示例

// connection_api.go
type SaveConnectionRequest struct {
    ID       uint   `json:"id"`
    Name     string `json:"name"`
    Type     string `json:"type"`
    Host     string `json:"host"`
    Port     int    `json:"port"`
    Username string `json:"username"`
    Password string `json:"password"`
    Database string `json:"database"`
    Options  string `json:"options"`
}

func (api *ConnectionAPI) SaveDbConnection(req SaveConnectionRequest) error {
    conn := &models.DbConnection{
        ID:       req.ID,
        Name:     req.Name,
        Type:     req.Type,
        Host:     req.Host,
        Port:     req.Port,
        Username: req.Username,
        Password: req.Password,
        Database: req.Database,
        Options:  req.Options,
    }
    return api.connService.SaveConnection(conn)
}

5.2 前端 Composables 依赖优化(中优先级)

问题:需要手动注入依赖,使用不够优雅。

优化方案

  1. 使用 provide/inject 或全局状态管理依赖
  2. Composables 内部自动获取依赖
  3. 保持向后兼容,支持手动注入

示例

// 使用 provide/inject
const resultState = useResultState()
const messageLog = useMessageLog()

provide('resultState', resultState)
provide('messageLog', messageLog)

// useSqlExecution 内部自动获取
export function useSqlExecution() {
  const resultState = inject<ReturnType<typeof useResultState>>('resultState')
  const messageLog = inject<ReturnType<typeof useMessageLog>>('messageLog')
  // ...
}

5.3 Service 层验证逻辑提取(中优先级)

问题:验证逻辑分散在 Service 方法中,代码重复。

优化方案

  1. 创建独立的验证器Validator
  2. 统一验证错误格式
  3. 可复用的验证规则

示例

// validator/connection_validator.go
type ConnectionValidator struct{}

func (v *ConnectionValidator) ValidateSave(conn *models.DbConnection) error {
    if conn.Name == "" {
        return fmt.Errorf("连接名称不能为空")
    }
    if conn.Type == "" {
        return fmt.Errorf("数据库类型不能为空")
    }
    if conn.Host == "" {
        return fmt.Errorf("主机地址不能为空")
    }
    return nil
}

5.4 Composables 组合优化(低优先级)

问题index.vue 中 composables 较多,可以进一步抽象。

优化方案

  1. 创建 useDbCli composable 作为统一入口
  2. 内部组合所有相关 composables
  3. 提供简洁的 API

示例

// composables/useDbCli.ts
export function useDbCli() {
  const connection = useDbConnection()
  const editor = useEditorState()
  const result = useResultState()
  const message = useMessageLog()
  const sql = useSqlExecution(result, message)
  const structure = useStructureState()
  const structureEdit = useStructureEdit()
  
  return {
    connection,
    editor,
    result,
    message,
    sql,
    structure,
    structureEdit
  }
}

六、架构检查清单

开发优先原则检查

  • 是否使用了 Vue 的响应式系统管理状态?
  • 是否使用了模板引用而非 DOM 查询?
  • 是否在正确的时机执行操作(通过 nextTickrequestAnimationFrame 等)?
  • 是否移除了不必要的重试循环?
  • 是否移除了过多的条件检查和兜底逻辑?
  • 代码是否简洁直接,易于理解?
  • 是否避免了防御性编程模式?

后端检查

  • API 方法参数不超过 3 个,超过使用结构体封装
  • 所有请求/响应结构体命名统一
  • Service 层验证逻辑清晰
  • 错误处理统一

前端检查

  • Composables 依赖关系清晰
  • 减少手动依赖注入
  • 代码简洁直接
  • 类型定义完善

设计美学检查

  • 参数数量符合约束≤3
  • 代码简洁易读
  • 命名一致统一
  • 结构清晰优雅

四、数据流规范

4.1 数据流向

用户操作
  ↓
组件事件
  ↓
Composable方法
  ↓
API调用
  ↓
后端Service
  ↓
Repository
  ↓
数据库

4.2 状态管理

  • 原则使用Composables管理状态
  • 位置composables/ 目录
  • 命名use{功能}State.ts

五、约束条件

5.1 后端约束

  • 方法参数不超过3个
  • 不返回 RetResult<Void> 类型
  • 使用分层架构,职责分离

5.2 前端约束

  • 使用Arco基础样式
  • 事件参数使用对象格式
  • 所有事件有类型定义

六、检查清单

架构检查

  • 分层架构清晰
  • 职责分离明确
  • 依赖方向正确
  • 符合架构规范