XYGo Admin 后端分层架构:Controller→Service→Logic→DAO 实战解析

XYGo Admin 后端分层架构:Controller → Service → Logic → DAO 实战解析

引言

在使用 GoFrame 开发中后台系统时,很多开发者会被一个问题困扰:代码到底该写在哪一层?Controller 里能不能写数据库查询?Logic 和 Service 有什么区别?DAO 是什么?这些困惑在团队协作中尤为突出------每个人有自己的"习惯写法",最终项目变成难以维护的"大泥球"。

XYGo Admin 作为一款基于 GoFrame + Vue3 的企业级中后台框架,提供了一套清晰的分层架构规范。本文通过实际代码示例,带你彻底理解这套分层设计,并掌握正确的开发姿势。

一、整体架构概览

XYGo Admin 的后端采用四层架构,请求处理流程如下:

```

HTTP Request

→ Middleware(鉴权、日志、响应包装)

→ Controller(参数校验、调用 Service)

→ Service(接口定义,自动生成)

→ Logic(业务逻辑实现)

→ DAO(数据库操作)

→ Database

```

每一层各司其职,职责边界非常清晰。下面逐层剖析。

二、Controller 层:只做"接"和"返"

Controller 是请求的入口,它的职责只有两件事:

  1. 接收并校验参数 :检查请求参数格式是否正确

  2. 调用 Service 并返回结果:不写任何业务逻辑

来看一个用户管理的 Controller 示例:

```go

// api/admin/user.go --- API 接口定义

type UserReq struct {

g.Meta `path:"/user/list" method:"GET" summary:"用户列表"`

Page int `json:"page" d:"1"`

PageSize int `json:"pageSize" d:"20"`

}

type UserRes struct {

List \[\]*userListVO `json:"list"`

Total int `json:"total"`

}

```

```go

// controller/admin/user.go --- 控制器

func (c *userController) List(ctx context.Context, req *v1.UserReq) (res *v1.UserRes, err error) {

return c.userService.List(ctx, req)

}

```

关键点:Controller 函数体只有一行,就是把参数传给 Service。如果你在 Controller 里写 `g.DB().Model("xy_user").Scan(...)`,那就破坏了架构。

三、Service 层:接口契约,自动生成

Service 层在 GoFrame 中是一个接口层,由 `gf gen service` 命令自动生成。开发者不需要手写它,相应的实现写在 Logic 中。

```go

// service/user.go --- 由 gf gen service 自动生成,不要手动修改

type IUser interface {

List(ctx context.Context, req *v1.UserReq) (res *v1.UserRes, err error)

}

```

这层的价值在于:接口与实现分离。Logic 层的实现只要满足这个接口,Controller 就不需要关心具体实现细节。后续替换实现(比如从 MySQL 迁到 TiDB),只需要改 Logic 层即可。

四、Logic 层:业务逻辑的核心战场

Logic 层是项目中最核心的代码层。所有业务逻辑都在这里实现

```go

// logic/user/user.go

type sUser struct{}

func init() {

service.RegisterUser(New())

}

func New() *sUser {

return &sUser{}

}

func (s *sUser) List(ctx context.Context, req *v1.UserReq) (res *v1.UserRes, err error) {

// 分页查询

res = &v1.UserRes{}

err = dao.User.Ctx(ctx).

Page(req.Page, req.PageSize).

Scan(&res.List)

if err != nil {

return nil, err

}

count, err := dao.User.Ctx(ctx).Count()

if err != nil {

return nil, err

}

res.Total = count

return

}

```

Logic 层的优势在于:

  • 可测试性 :业务逻辑集中在一层,可以针对 Logic 编写单元测试

  • 可复用性 :多个 Controller 可以调用同一段 Logic 代码

  • 可维护性:业务变更时只需要修改 Logic 层的代码

五、DAO 层:数据库访问抽象

DAO(Data Access Object)是对数据库操作的封装,由 `gf gen dao` 命令自动生成。DAO 层位于 `internal/dao/` 目录下,而自动生成的内部实现则在 `dao/internal/` 中。

核心规则

  • `dao/internal/` 下的文件由 CLI 自动生成,不要手动修改

  • 扩展的查询方法写在 `dao/` 外层

```go

// dao/internal/user.go --- 自动生成,不要修改

type User struct {

Table string

Columns userColumns

}

type userColumns struct {

Id string

Username string

Password string

Nickname string

Email string

CreatedAt string

UpdatedAt string

}

```

当需要扩展自定义查询方法时,不在自动生成的文件里改,而是在外层扩展:

```go

// dao/user.go --- 自定义扩展方法

package dao

func (d *userDao) GetActiveUsers(ctx context.Context) (\[\]entity.User, error) {

return d.User.Ctx(ctx).

Where("status", 1).

Where("deleted_at", 0).

All()

}

```

六、实用开发建议

1. 使用 CRUD 生成器加速开发

XYGo Admin 内置了代码生成器,从数据表生成完整的前后端代码(包括 DAO、Entity、Logic、Controller 和 Vue 页面)。推荐开发流程是:

  1. 设计好数据库表结构

  2. 使用代码生成器生成初始代码

  3. 在 Logic 层补充业务逻辑

  4. 调整前端页面细节

这在大多数 CRUD 场景下,能节省 70% 以上的重复工作量。

2. 规范命名

  • Controller 文件:`controller/admin/模块名.go`

  • Logic 文件:`logic/模块名/模块名.go`

  • DAO 文件:`dao/表名.go`

3. 理解 Middleware 层

公共逻辑放在中间件,不要在 Controller 里重复处理。例如:

```go

// middleware/admin_auth.go --- 权限校验中间件

func AdminAuth(r *ghttp.Request) {

token := r.Cookie.Get("admin_token")

if token.IsEmpty() {

r.Response.WriteJson(g.Map{"code": 401, "msg": "未登录"})

r.Exit()

}

// 解析 token、获取用户信息、注入上下文

ctxUser := parseToken(token.String())

r.SetCtx(ghttp.PutCtx(r.Context(), "user", ctxUser))

r.Middleware.Next()

}

```

七、常见误区

| 误区 | 正确做法 |

|------|---------|

| Controller 里写 SQL 查询 | Controller 只做参数接收和返回,查询写在 Logic 层 |

| 手动修改 `dao/internal/` 文件 | 不要改,改完后下次 `gf gen dao` 会被覆盖 |

| 在 Logic 里直接调用另一个 Logic | 通过 Service 接口调用,保持层级清晰 |

| 手写 Service 接口 | Service 由 `gf gen service` 自动生成,手写容易不一致 |

总结

XYGo Admin 的四层架构设计,本质是约定大于配置的思想体现。每层都有明确的职责边界,开发者不需要纠结"这段代码放哪",按照规范写即可。这种分层带来的好处在大规模项目中尤为明显------代码可读性高、团队协作顺畅、重构成本低。

如果你是 GoFrame 新手,建议从 CRUD 生成器入手,先自动生成一套标准代码,然后逐层阅读生成的代码,感受清晰的分层结构。等熟悉之后再尝试手写业务板,你会发现自己已经自然而然地遵循了这套规范。

> 更多 XYGo Admin 开发文档和最佳实践,可参考官方网站

相关推荐
myenjoy_11 小时前
大规模采集架构——从单台网关到千点集群
架构·wpf
qq_411262422 小时前
AI-02模组架构与Coze智能体接入说明
人工智能·ai·架构·esp32-c3·coze·四博
HavenlonLabs2 小时前
三年内,AI 控制会走向安全的一线
人工智能·安全·金融·架构·安全架构
故渊at2 小时前
第十三板块:Android 综合架构与未来演进 | 第三十一篇:Android 架构演进与 Fuchsia OS 的挑战
android·架构·宏内核·微内核·fuchsia·ipc 性能博弈
咚为2 小时前
Claude Code 深度定制指南:从分层架构到 AI 参谋系统的高级搭建实践
人工智能·架构
X54先生(人文科技)3 小时前
X54先生与“启”关于涌现对话
人工智能·架构·开源·零知识证明
“码”力全开3 小时前
云边端协同架构:基于 Docker 与边缘计算的 GB28181/RTSP 异构视频 AI 管理平台设计(附源码交付)
人工智能·docker·架构
TheRouter3 小时前
LLM 应用的 Guardrails 工程:5 层安全防护架构,为什么一层不够
安全·ai·架构
搞点AI3 小时前
深入理解 vLLM 的 Block 机制
架构