在之前的章节 代码分层设计 有提及到"模型"的概念。
这一章节,我们集中介绍一下在GoFrame
中关于模型的定义以及对应的管理。
一、数据模型
数据模型又叫做实体模型,主要是来自于底层持久化数据库的数据结构,例如:MySQL
、Redis
、MongoDB
、Kafka
等等。这部分数据结构是由第三方系统维护的,可以通过工具对其集合数据结构进行识别,并自动生化成对应的程序数据模型代码。这部分数据模型的代码位于/internal/model/entity
目录下。开发者不需要手动在程序中维护数据模型,在GoFrame
框架规范中,数据模型统一使用CLI
工具统一维护,代码自动生成。
数据模型示例
二、业务模型
业务模型主要包含两类:接口输入/输出模型 与 业务输入/输出模型。
接口输入/输出模型
接口输入/输出模型用于系统/服务间的接口交互,定义在api
接口层中,供工程项目所有的层级调用,例如controller, logic, model
中均可以调用api
层的输入输出模型,但是api
层仅用于与外部服务的接口交互,该模型中不能调用或者引用内部的模型如model
模型。在GoFrame
框架规范中,这部分输出输出模型名称以XxxReq
和XxxRes
格式命名。
接口输入模型示例
业务输入/输出模型
业务输入/输出模型用于服务内部模块/组件之间的方法调用交互,特别是controller->service
或者service->service
之间的调用。这部分模型定义在model
模型层中。在GoFrame
框架规范中,这部分输入输出模型名称通常以XxxInput
和XxxOutput
格式命名。
业务输入模型与业务输出模型示例
特殊的业务模型DO
在GoFrame
有一类特殊的业务模型DO
,介于业务模型与数据模型之间,主要用于结合框架强大的ORM
组件大大简便DAO
数据访问操作。
DO主要用于DAO数据访问操作
三、其他模型
还有内部私有的模型,用于模块内部调用,例如在logic
各个业务模块内部定义的模型,用于内部逻辑,不对外公开。
11 Comments
ayamzh
强哥,接口的req rsp是否可以考虑提到另外的地方,混在model里,不太好管理查询,可以考虑弄个 msg/request msg/response,或者考虑放到api/msg/xxxx下, 因为这个和api层是强关联的
郭强
哈哈,我看你提了两个问题都是提到了
the very point
上,看样子大佬也是过来人。当然,考虑过,现在的这个代码管理方式算是比较务实和简便的方式,大佬和萌新都好理解。统一放model
中管理确实会引起一些混淆,不过也是有利有弊,这种常见问题具体在这篇文章中也有介绍过:代码分层设计虾子
强哥,笔误了:接口输入/输入模型用于 和 业务输入/输入模型
新版本学习中,收获满满。
白夜
数据模型+业务模型,总共有4个模型:API的req/res、model的entity、model的input/output、service的do。在做restful API时发现这4个模型有可能内容字段极为类似的,比如创建一个用户,表结构如下:
想要做一个get user detail的操作,4个模型极为类似,并且entity和output一模一样;也和do极为类似:do是自动生成,使用interface{}代替了string,增加了meta信息用来做orm,而res与前3者相比,
password作为敏感字段不返回,其他全部一致。所以,想问下:
4个模型极为相似时,是否有方法做合并或者抽取公共部分来减少重复代码?
郭强
可以的,考虑结构体嵌套
struct embedded
白夜
那这个公共的结构体,我放到 API下,然后其他的模型嵌套 API下的struct? 会不会破坏分层之间的 边界?
另外,do/entity如果重新生成,然后会覆盖。这个怎么办呢?
郭强
一般是
api
嵌套model/entity
,由上至下,没有反过来的。youxue2016
在cmd.go中新绑定了一个路由,然后控制器,模型,dao,什么的都该怎么弄呢.都是手动建立吗?能不能出一个文档呀.现在的gf2版本完全摸不到头脑,无从下手啊
白夜
可以参看 示例仓库: https://github.com/gogf/focus-single
一时半会儿想不出名字
默默收藏此图反复背诵誊写
钱加倍
此图甚是牛逼 简直醍醐灌顶