Compare commits

..

103 Commits

Author SHA1 Message Date
dayjoy
8d028d116c feat: 简化技术描述语言(3~4) 2025-08-20 11:20:58 +08:00
dayjoy
47199b895c feat: 简化技术描述语言(2.12~2.16) 2025-08-20 11:18:10 +08:00
dayjoy
f253b4f628 feat: 简化技术描述语言(2.10~2.11) 2025-08-20 11:02:31 +08:00
dayjoy
1dcb2ce6a0 feat: 简化技术描述语言(2.9) 2025-08-20 10:44:36 +08:00
dayjoy
11eb3f3b37 feat: 简化技术描述语言(2.8) 2025-08-20 10:36:53 +08:00
dayjoy
9d0ccd1372 feat: 简化技术描述语言(2.7) 2025-08-20 10:28:34 +08:00
dayjoy
bd1cf2a5a4 feat: 简化技术描述语言(1~2.6) 2025-08-19 18:51:41 +08:00
dayjoy
10af7636a9 feat: 文件改名 2025-08-19 16:45:57 +08:00
dayjoy
ea16681047 feat: 文件改名 2025-08-19 16:44:22 +08:00
dayjoy
132e666a65 feat: 更新TOCO平台简介 2025-08-18 16:43:31 +08:00
dayjoy
5cb4d8c451 feat: 添加TOCO平台简介 2025-08-18 16:40:17 +08:00
oyo
0337f669ea 更新 llms-full.txt 2025-08-17 14:10:46 +08:00
ycl
191ef8c1eb 更新 llms-full.txt 2025-08-15 18:08:07 +08:00
ycl
341eae8c7b 更新 llms-full.txt 2025-08-15 18:03:21 +08:00
ycl
73ccf32447 更新 llms-full.txt 2025-08-14 11:07:23 +08:00
oyo
337ba0ea99 更新 llms-full.txt 2025-08-14 10:45:02 +08:00
ycl
66568700de 更新 llms-full.txt 2025-08-12 14:48:49 +08:00
oyo
de30f67e50 更新 llms-full.txt 2025-08-11 18:19:46 +08:00
oyo
8dddf1b5c0 更新 llms-full.txt 2025-08-11 17:41:13 +08:00
oyo
627fd79c46 更新 llms-full.txt 2025-08-11 12:13:28 +08:00
ycl
be247c12cf 更新 llms-full.txt 2025-08-10 16:34:51 +08:00
ycl
cae9ef9ca5 更新 llms-full.txt 2025-08-10 15:16:29 +08:00
ycl
02533b17e2 更新 llms-full.txt 2025-08-10 11:15:03 +08:00
oyo
d99985b72e 更新 llms-full.txt 2025-08-08 17:40:19 +08:00
oyo
d77d0366da 更新 llms-full.txt 2025-08-08 17:38:48 +08:00
oyo
4143c28560 更新 llms-full.txt 2025-08-08 12:10:23 +08:00
oyo
b72d9dd628 更新 llms-full.txt 2025-08-08 11:52:48 +08:00
oyo
aa8b21bb5f 更新 llms-full.txt 2025-08-08 11:48:34 +08:00
oyo
35fc099370 更新 llms-full.txt 2025-08-07 12:32:34 +08:00
oyo
b0d1c9e402 更新 llms-full.txt 2025-08-07 12:26:45 +08:00
ycl
3ab49979d3 更新 llms-full.txt 2025-08-07 12:16:49 +08:00
oyo
c6fd6daed5 更新 llms-full.txt 2025-08-07 12:05:30 +08:00
ycl
d59871ad21 更新 llms-full.txt 2025-08-07 11:29:28 +08:00
oyo
29666b7b9b 更新 llms-full.txt 2025-08-07 11:26:23 +08:00
oyo
979ee3a745 更新 llms-full.txt 2025-08-06 14:25:33 +08:00
oyo
207e18835a 更新 llms-full.txt 2025-08-06 11:28:03 +08:00
oyo
eac3a4fb93 更新 llms-full.txt 2025-08-05 14:56:51 +08:00
oyo
0cfeabcb16 更新 llms-full.txt 2025-08-05 14:37:26 +08:00
oyo
7ae8d80e31 更新 llms-full.txt 2025-08-05 14:05:45 +08:00
ycl
a139300b9e 更新 llms-full.txt 2025-08-05 12:05:20 +08:00
ycl
cdecfa028b 更新 llms-full.txt 2025-08-05 11:45:20 +08:00
oyo
3f81639b9b 更新 llms-full.txt 2025-08-05 10:11:04 +08:00
ycl
e36464eabc 更新 llms-full.txt 2025-08-01 18:30:31 +08:00
oyo
08760b6f57 更新 llms-full.txt 2025-08-01 16:53:33 +08:00
oyo
479548b334 更新 llms-full.txt 2025-07-31 10:22:29 +08:00
1b7022466d 更新 coding-llms-full.txt 2025-07-29 14:37:20 +08:00
oyo
9daa17519d 更新 llms-full.txt 2025-07-28 19:18:21 +08:00
oyo
5671a0d36e 更新 llms-full.txt 2025-07-28 19:17:52 +08:00
oyo
d025d0db49 更新 llms-full.txt 2025-07-28 18:26:03 +08:00
ycl
8916d2bdb0 更新 llms-full.txt 2025-07-28 14:51:41 +08:00
oyo
45ac3fd8ef 更新 llms-full.txt 2025-07-28 10:55:53 +08:00
oyo
5268e1f170 更新 llms-full.txt 2025-07-28 10:44:46 +08:00
oyo
ff58ff2fd7 更新 llms-full.txt 2025-07-27 16:00:14 +08:00
ycl
b75b4c9229 更新 llms-full.txt 2025-07-25 16:16:23 +08:00
ycl
120b7ee161 更新 llms-full.txt 2025-07-25 15:59:06 +08:00
ycl
2c18cb147c 更新 llms-full.txt 2025-07-25 10:16:43 +08:00
ycl
97083d3272 更新 llms-full.txt 2025-07-24 14:50:16 +08:00
ycl
b575f39854 更新 llms-full.txt 2025-07-23 10:52:03 +08:00
ycl
33662b2e33 更新 llms-full.txt 2025-07-23 10:17:23 +08:00
ycl
1246cf4ff7 更新 llms-full.txt 2025-07-23 10:14:12 +08:00
ycl
3569493428 更新 llms-full.txt 2025-07-23 09:58:30 +08:00
ycl
398ddd673f 更新 llms-full.txt 2025-07-22 16:54:24 +08:00
ycl
cff7c151d9 更新 llms-full.txt 2025-07-22 16:13:34 +08:00
ycl
0f9d1774e6 更新 llms-full.txt 2025-07-22 16:04:55 +08:00
ycl
2e396f0100 更新 llms-full.txt 2025-07-22 15:53:22 +08:00
ycl
8e6968c27c 更新 llms-full.txt 2025-07-22 15:24:02 +08:00
ycl
e90f882b9a 更新 llms-full.txt 2025-07-22 14:51:28 +08:00
c08274d900 Add coding-llms-full.txt 2025-07-22 13:48:08 +08:00
ycl
1dc3af15f4 更新 llms-full.txt 2025-07-21 10:15:27 +08:00
ycl
952c8d0b64 更新 llms-full.txt 2025-07-21 10:07:24 +08:00
oyo
34c1c48f14 更新 llms-full.txt 2025-07-20 15:53:28 +08:00
ycl
99581be3cb 更新 llms-full.txt 2025-07-17 14:07:21 +08:00
ycl
18f7ad590e 更新 llms-full.txt 2025-07-17 14:01:37 +08:00
ycl
59b601fede 更新 llms-full.txt 2025-07-17 12:18:12 +08:00
ycl
ded0c82d6f 更新 llms-full.txt 2025-07-17 11:00:51 +08:00
oyo
939726f0fd 更新 llms-full.txt 2025-07-16 19:11:31 +08:00
oyo
7c9168318f 更新 llms-full.txt 2025-07-16 19:08:36 +08:00
oyo
662ebf1215 更新 llms-full.txt 2025-07-14 19:28:47 +08:00
oyo
512df24380 更新 llms-full.txt 2025-07-14 19:27:15 +08:00
ycl
f23ecb3f2f 更新 llms-full.txt 2025-07-14 19:03:22 +08:00
oyo
a6e460a05c 更新 llms-full.txt 2025-07-14 17:14:47 +08:00
ycl
39de528ba1 更新 llms-full.txt 2025-07-13 17:39:43 +08:00
oyo
02b6befd21 更新 llms-full.txt 2025-07-11 11:33:22 +08:00
oyo
996d9cceb9 更新 llms-full.txt 2025-07-11 11:24:31 +08:00
oyo
b8a7593a6a 更新 llms-full.txt 2025-07-10 19:15:48 +08:00
ycl
69c7ab9f36 更新 llms-full.txt 2025-07-04 16:11:38 +08:00
oyo
4bc07060f2 更新 llms-full.txt 2025-07-04 15:56:22 +08:00
a29f87d0a3 强调IgnoredException的引用路径 2025-07-04 15:53:49 +08:00
oyo
810d43314c 更新 llms-full.txt 2025-07-04 15:51:32 +08:00
ycl
d61c04064c 更新 llms-full.txt 2025-07-04 14:25:48 +08:00
ycl
6fe83d6d11 更新 llms-full.txt 2025-07-04 13:58:02 +08:00
oyo
a6ae76b458 更新 llms-full.txt 2025-07-04 11:25:23 +08:00
oyo
891caae79c 更新 llms-full.txt 2025-07-03 15:22:29 +08:00
ycl
0ec32c2239 更新 llms-full.txt 2025-07-02 18:48:49 +08:00
ycl
d4705d7717 更新 llms-full.txt 2025-07-02 18:45:52 +08:00
ycl
fba0efd2dc 更新 llms-full.txt 2025-07-02 15:47:19 +08:00
oyo
8a2f4ccb41 更新 llms-full.txt 2025-07-02 15:33:14 +08:00
oyo
02c5047071 更新 llms-full.txt 2025-07-02 15:21:49 +08:00
ycl
31dc91447d 更新 llms-full.txt 2025-07-02 15:07:32 +08:00
ycl
b60d6eca30 更新 llms-full.txt 2025-07-02 15:03:36 +08:00
ycl
cd88bd34d2 更新 llms-full.txt 2025-06-30 11:26:24 +08:00
ycl
a093b0f5d3 更新 llms-full.txt 2025-06-30 10:39:33 +08:00
ycl
f39b0b2125 更新 llms-full.txt 2025-06-29 17:24:56 +08:00
5 changed files with 1697 additions and 276 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/.idea

0
code-guidelines.md Normal file
View File

209
knowledge-brief.md Normal file
View File

@@ -0,0 +1,209 @@
# TOCO平台简介
## 平台概述
TOCO是一个基于DDD、分层设计、CQRS等理论的专业研发平台主要目标是提供软件设计能力设计结果可直接转换为标准格式的代码。平台覆盖从数据库到API的全链路能够显著提升开发设计和编程效率。
## 核心设计理念
TOCO采用严格的分层架构
- **entrance层**API控制器层
- **service层**:服务层,处理业务逻辑
- **manager层**管理层处理DTO相关逻辑
- **persist层**:持久化层,处理数据访问
- **common层**:公共层,存放枚举、工具类等
技术栈Java + SpringBoot + MyBatis-plus+ Hibernate
## 重要设计元素详解
### 1. 模块Module
- **作用**系统领域的具体细分映射为Java工程中的module
- **命名规则**:小写英文字母+下划线,如`meeting``user_detail`,全局唯一
- **代码结构**每个Module生成独立的Java Module采用entrance、service、manager、persist、common分层
### 2. 枚举Enum
- **作用**:表达常量值集合,可被其他模块使用
- **命名规则**:以`_enum`结尾,全局唯一
- **生成位置**`**.common.enums`包路径下
- **修改建议**:不建议修改
### 3. 值对象EO
- **作用**POJO对象结构可被其他模块使用
- **命名规则**:以`_eo`结尾,全局唯一
- **字段限制**只能为基本类型、EO、Enum类型
- **生成位置**`**.persist.eo`包路径下
### 4. 实体关系Entity
- **作用**:对应数据库表,定义实体间的外键依赖关系
- **生成产物**
- 结构定义类:`**.persist.dos`
- Mapper类`**.persist.mapper.mybatis`
- Dao接口`**.persist.mapper`
- Dao实现`**.persist.mapper`
### 5. 聚合对象BO
- **核心概念**:封装一组密切关联的实体,以聚合根为起点,按层级关系组装其他实体
- **重要特性**
- 提供数据操作入口和内存一致性视图
- 只能在单一模块中组合
- 一个实体只能属于一个聚合对象
- **生成位置**`**.manager.bo`包路径下
- **修改建议**建议修改BO中的`validateAggregate``valid`方法进行业务不变性校验
### 6. 数据传输对象DTO
- **核心概念**以某个Entity为基础通过外键关系关联多个Entity的数据结构
- **分类**
- **BaseDTO**每个Entity自动生成一个包含Entity全部字段
- **普通DTO**派生自BaseDTO可增加扩展字段或自定义字段
- **字段扩展方式**
- **正向替换**将外键字段替换为对应Entity的DTO对象
- **反向注入**在当前Entity中注入其他Entity的DTO对象或列表
- **预定义方法**TOCO自动为每个DTO生成基于唯一索引的RPC方法
- **生成产物**
- 结构定义:`**.manager.dto`
- Manager`**.manager`
- Converter`**.manager.converter`
### 7. 视图对象VO
- **作用**用于视图层与前端数据传输作为HTTP API返回值
- **派生关系**通常派生自BaseDTO或其他DTO
- **分类**
- **根VO**需要创建有uuid标识
- **子VO**自动创建附属于根VO
- **与DTO区别**VO更接近UI展示可裁剪冗余字段DTO更接近数据模型复用性强
- **转换方法**
- 基础转换:`convertTo${VoName}`
- 带数据拼装:`convertAndAssembleData`
### 8. 查询对象WO
- **作用**表达以某Entity为基础通过外键关系关联多个Entity的查询结构
- **用途**作为ReadPlan的查询上下文使用
### 9. 读方案ReadPlan
- **作用**描述如何基于查询对象从数据库获取DTO/VO列表数据
- **核心能力**
- 复杂查询条件组合
- 数据拼装和过滤
- 分页和排序
- **能力边界**
- 支持等值、模糊、范围、包含查询
- 支持列表属性过滤
- 不支持复杂统计和聚合计算
- **使用原则**根据主键或唯一索引查询时优先使用DTO预定义方法其他复杂查询使用读方案
- **生成产物**自动生成RPC方法和对应的QTO
### 10. 写方案WritePlan
- **重要限制**:一个写方案只能操作一个聚合内的表,无法跨聚合操作
- **操作类型**
- `CREATE`:创建单个实体
- `UPDATE`:更新单个实体
- `DELETE`:删除单个实体
- `CREATE_ON_DUPLICATE_UPDATE`:创建或更新单个实体
- `FULL_MERGE`:批量更新列表数据(全量替换)
- `PARTIAL_MERGE`:批量更新列表数据(部分更新)
- **生成产物**自动生成RPC方法和对应的BTO
### 11. 查询传输对象QTO
- **作用**:读方案的查询参数结构
- **使用场景**作为API参数禁止用作写参数
### 12. 业务变更传输对象BTO
- **作用**:写方案的参数结构
- **特点**:树形结构,最外层为聚合根
- **使用场景**作为API参数禁止用作查询参数
### 13. 服务层方法RPC
- **分类**
- **公开RPC**:可被其他模块订阅调用
- **非公开RPC**:只能被当前模块调用
- **创建方式**
- DTO创建后自动生成
- 读方案自动生成
- 写方案自动生成
- 手动创建自定义RPC
- **参数限制**只能为QTO、BTO、Enum、基本类型
- **返回值限制**只能为DTO、Enum、基本类型
### 14. 应用程序接口API
- **作用**定义对外暴露的HTTP接口
- **URI规范**:一般为`/api/${moduleName}/xxx`格式
- **参数限制**只能为QTO、BTO、EO、Enum、基本类型
- **返回值限制**只能为VO、Enum、基本类型
- **分页处理**框架自动包装返回值code、message、data
### 15. 流程服务FunctionFlow
- **使用场景**
- API/RPC涉及超过3个写服务时必须使用
- 用户明确要求时使用
- **节点类型**
- 顺序节点:封装业务逻辑
- 条件节点:封装判断逻辑
- 选择节点:封装分支选择逻辑
- 开始节点:流程起点
- **设计原则**:以数据内聚为首要考虑,每个节点围绕核心写服务
## 数据获取流程
### DTO获取流程
1. **主键/唯一索引查询**:使用预定义方法
2. **复杂查询条件**:使用读方案
### VO获取流程
1. **主键/唯一索引查询**预定义方法获取DTO → convert方法转换为VO
2. **复杂查询有对应DTO读方案**读方案获取DTO → convert方法转换为VO
3. **复杂查询无对应DTO读方案**直接使用VO读方案
## 接口设计最佳实践
### 参数类型选择优先级
1. **读场景**优先使用QTO
2. **写场景**优先使用BTO
3. **补充参数**基本类型、Enum、EO
### 返回值类型选择
1. **RPC返回值**DTO、Enum、基本类型
2. **API返回值**VO、Enum、基本类型
### 绝对禁止的用法
- DTO、VO不能作为参数类型
- QTO、BTO不能作为返回值类型
- Service层不能返回VO
- VO不能作为RPC返回值
## 代码修改指南
### 推荐修改的位置
1. **BO类**`validateAggregate``valid`方法中添加业务校验
2. **Converter类**:自定义字段的数据获取逻辑
3. **Service类**:业务逻辑实现
4. **API Controller**:接口实现逻辑
### 禁止修改的内容
1. 带有`@AutoGenerated(locked=true)`的类和方法
2. DTO、VO的结构定义
3. Manager类的系统生成方法
4. Mapper类的结构定义
## 并发控制最佳实践
在处理先读后更新的场景时,为避免并发引起的数据脏写:
1. **写方案中使用incr字段**
2. **BoService中添加校验**:如`if(userBo.getBalance() >= 0)`
3. **聚合校验**在BO的业务不变性校验中添加约束条件
## 项目结构导航
标准查找流程:
- **API查找**`modules/{模块名}/entrance/web/controller/`
- **DTO查找**`modules/{模块名}/manager/dto/`
- **Service查找**`modules/{模块名}/service/`
- **数据层查找**`modules/{模块名}/persist/`
## 重要注意事项
1. **跨模块调用**必须通过订阅RPC使用RpcAdapter进行调用
2. **变量命名**RpcAdapter注入时变量名必须是类名首字母小写
3. **自定义字段逻辑**必须在BaseConverter的Map转换方法中实现
4. **读写分离**读操作使用MyBatis-plus写操作使用Hibernate
5. **严格分层**:各层职责明确,不能越层调用

1487
knowledge.md Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,276 +0,0 @@
## TOCO知识库
### **1. TOCO 平台概览:**
- **1.1 平台简介:** TOCO是一款重视软件设计及核心代码自动生成的专业研发平台。其基于DDD、分层设计、CQRS等经典研发理论从数据库到API全部覆盖可显著提升开发设计和编程效率帮助开发团队实现更高的质量和生产力
- **1.2 核心价值/目标用户:** 从软件工程理论出发,提供软件设计能力,设计结果可直接转换为标准格式的代码,提升编码一致性及效率
- **1.3 主要特性概览:** 可视化设计、模型关联、多人协作、代码生成器等
### **2. TOCO 设计元素:**
#### **2.1 模块 (Module)**
- **定义与用途:** 在TOCO中我们将系统领域细分为具体的模块映射为Java工程中的module。这些模块代表了系统的叶子子域每个模块负责特定的功能。模块划分有助于系统的可维护性和可扩展性并能提高开发效率和代码质量
#### **2.2 枚举 (Enum)**
- **定义与用途:** Enum用来表达一些常量值的集合可被其他模块使用可被用来做为字段的类型
* **代码产物和修改建议**
* **生成产物**在common模块中生成一个Java类
* **职责:** 表达Enum的数据结构
* **命名规则**类名以Enum结尾
* **类路径:** 位于 ```**.common.enums``` 包路径下
* **唯一标识符位置:** 其对应的唯一标志在类注解@AutoGenerated中指定 ,uuid规则: ${Enum在TOCO中的uuid}|ENUM|DEFINITION
- **生成代码:** Enum会在common层生成Enum文件如StatusEnum
- **修改建议:** 不建议修改
#### **2.3 值对象 (Eo)**
- **定义与用途:** EO为一种POJO对象结构可被其他模块使用可被用来做为实体字段的类型。
* **代码产物和修改建议**
* **生成产物**在persist层生成结构定义类文如AddressEo
* **职责:** 表达POJO数据结构
* **命名规则**类名以Eo结尾
* **类路径:** 位于 ```**.persist.eo``` 包路径下
* **唯一标识符位置:** 其对应的唯一标志在类注解@AutoGenerated中指定 ,uuid规则: ${Eo在TOCO中的uuid}|EO|DEFINITION
- **修改建议:** 不建议修改
#### **2.4 实体关系 (ER / Entity)**
- **定义与用途:** 实体及其关系。一个实体一般对应一个数据库表,关系为实体间的外键依赖关系
- **代码产物和修改建议**
- 结构定义
* **生成产物**Java类按照Mybatis-plus的要求生成
* **职责:** 按照Mybatis-plus的要求生成结构定义类文件
* **类路径:** 位于 ```**.persist.dos``` 包路径下
* **唯一标识符位置:** 其对应的唯一标志在类注解@AutoGenerated中指定 ,uuid规则: ${Entity在TOCO中的uuid}|ENTITY|DEFINITION
- Mapper
* **生成产物**在persist层生成Mybatis-plus的Mapper类
* **职责:** 提供Mapper给Mybatis-plus框架
* **命名规则**类名以Mapper结尾(${entityName}Mapper)
* **类路径:** 位于 ```**.persist.mapper.mybatis``` 包路径下
* **唯一标识符位置:** 其对应的唯一标志在类注解@AutoGenerated中指定 ,uuid规则: ${Eo在TOCO中的uuid}
- Dao接口
* **生成产物**在persist层生成Dao接口
* **职责:** 提供Entity数据的查询接口为service层提供数据访问入口
* **命名规则**类名以Dao结尾(${entityName}Dao)
* **类路径:** 位于 ```**.persist.mapper``` 包路径下
* **唯一标识符位置:** 其对应的唯一标志在类注解@AutoGenerated中指定 ,uuid规则: ${Entity在TOCO中的uuid}|ENTITY|IDAO
- Dao实现
* **生成产物**在persist层生成Dao接口的实现类文件
* **职责:** 通过调用Mapper实现实现Dao接口
* **命名规则**类名以DaoImpl结尾(${entityName}DaoImpl)
* **类路径:** 位于 ```**.persist.mapper``` 包路径下
* **唯一标识符位置:** 其对应的唯一标志在类注解@AutoGenerated中指定 ,uuid规则: ${Entity在TOCO中的uuid}|ENTITY|DAO
- **修改建议:** 不建议修改
#### **2.5 聚合对象 (BO/业务对象)**
- **定义与用途:** 在TOCO中聚合对象是对一组密切关联的实体的封装。聚合对象从单一实体开始这个实体我们称为聚合根通过实体间关系不断的顺序将其他实体按层级关系组装进这个聚合对象。聚合对象可以按实体表达为树形结构。聚合对象提供了这组实体的内存一致性视图提供数据操作入口。由于写操作的内聚性聚合对象只能在单一模块中组合而且一个实体只能属于一个对象。同样如果有实体不在任何一个聚合对象中TOCO将无法提供与之相关的写方法。
- **代码产物和修改建议**
- 综述
- 业务对象包含多个Entity通过业务对象的嵌套组合表达了Entity之间的关系如果一个业务对象包含了子对象则会生成BO和BaseBO,BaseBO封装实体属性和关系子类留给业务扩展逻辑
如果是叶子节点不存在子对象的BO则直接生成BO类文件不生成BaseBO类文件
- BO
* **生成产物**在Manager层生成聚合对象类文件符合Hibernate的标准
* **职责:** 定义聚合对象,多个聚合对象组合成层级结构实现充血模型,支持写链路上的数据变更,监听数据变更,支持数据校验
* **命名规则**类名以BO结尾(${entityName}BO)
* **类路径:** 位于 ```**.manager.bo``` 包路径下
* **唯一标识符位置:** 其对应的唯一标志在类注解@AutoGenerated中指定 ,uuid规则: ${Entity在TOCO中的uuid}|BO|DEFINITION
- **修改建议:** 建议修改BO中的validateAggregate或valid方法。不建议修改检验方法以外的其他代码如果发现需求中有业务不变性校验**注意** 上述的校验方法,在写方案内部由框架触发调用,而不是业务代码显式调用
- BaseBO
* **生成产物**对于存在子BO的聚合对象封装不变的代码部分
* **职责:** 定义聚合对象,多个聚合对象组合成层级结构实现充血模型,支持写链路上的数据变更,监听数据变更,支持数据校验
* **命名规则**类名以BO结尾(${entityName}BO)
* **类路径:** 位于 ```**.manager.bo``` 包路径下
* **唯一标识符位置:** 其对应的唯一标志在类注解@AutoGenerated中指定 ,uuid规则: ${Entity在TOCO中的uuid}|BO|DEFINITION
- **修改建议:** 建议修改BO中的validateAggregate或valid方法如果发现需求中有业务不变性校验;不建议修改检验方法以外的其他代码
#### **2.6 数据传输对象 (DTO)**
- **定义与用途:** 在TOCO中DTO表达某个Entity为基本通过外键关系不断关联多个Entity的数据结构。DTO还隐式表达了数据的取数拼装这种拼装符合外键关系。往往被当做RPC的返回值、或读方案的返回值使用不建议把DTO作为入参。注意DTO不能作为HTTP API的返回值。DTO分为BaseDTO和普通DTOBaseDTO派生自Entity包含Entity的所有字段每个Entity有且仅有一个BaseDTO普通DTO派生自BaseDTO包含BaseDTO的所有字段且可以增加扩展字段或自定义字段
- **代码产物和修改建议**
- 结构定义
* **生成产物**一个Java类
* **职责:** 表达DTO的数据结构
* **命名规则**类名以Dto结尾
* **类路径:** 位于 ```**.manager.dto``` 包路径下
* **唯一标识符位置:** 其对应的唯一标志在类注解@AutoGenerated中指定,uuid规则: ${DTO在TOCO中的uuid}|DTO|DEFINITION
- **Manager**
* **生成产物:** Java接口以及实现类
* **命名规则:** 接口类名以Manager结尾、实现类名以ManagerImpl结尾(${DtoName}Manager)、基类以名ManagerBaseImpl结尾(${DtoName}ManagerImpl)
* **职责:** 提供了DTO数据的获取的接口包括根据id单个、id列表批量获取、以及根据DTO对应的实体的数据库索引获取
* **类路径:** 位于 ```**.manager``` 包路径下
* **唯一标识符位置:** 其对应的唯一标志在类注解@AutoGenerated中指定,uuid规则: ${DTO在TOCO中的uuid}|DTO|MANAGER
- **Converter**
* **生成产物:** Java实现类以及基类
* **命名规则:** 实现类名以Converter结尾(${DtoName}Converter)、基类名以BaseConverter结尾(${DtoName}BaseConverter)
* **职责:** Entity转换到BaseDTO或则BaseDTO转化为普通DTO从Entity转为BaseDTO的方法命名为convert${EntityName}To${DtoName}从BaseDTO转换为DTO的方法命名为convert${BaseDtoName}To${DtoName}
* **类路径:** 位于 ```**.manager.converter``` 包路径下
* **唯一标识符位置:**
* 实现类Converter 其对应的唯一标志在类注解@AutoGenerated中指定,uuid规则: ${DTO在TOCO中的uuid}|DTO|CONVERTER
* 基类BaseConverter 其对应的唯一标志在类注解@AutoGenerated中指定,uuid规则: ${DTO在TOCO中的uuid}|DTO|BASE_CONVERTER
- **例子:**
* 如UserDto、UserDtoManager、UserDtoConverter extends UserDtoBaseConverter、UserDtoService或名称为${DtoName}Service内部包含getById,getByIds等方法。如果Dto为UserBaseDto则生成的类名为UserBaseDtoService
- **修改建议:**
- 建议在Service与BaseConverter中进行代码扩展不建议修改结构定义文件和Manager文件。其中DTO的**自定义字段**由于不直接派生自Entity所以一般会对应取数逻辑代码。通常如果涉及到数据获取、计算和拼装批量处理的性能最好所以代码位置**必须**放在BaseConverter中已经自动生成的**列表**转换方法中批量取数组装如UserBaseDtoBaseConverter.convertUserToUserBaseDto(List<User>)或UserDtoBaseConverter.convertUserBaseDtoToUserDto(List<UserBaseDto>)
#### **2.7 视图对象 (VO)**
- **定义与用途:** 在TOCO中VO表达某个BaseDTO(如果用户指明派生源也可使用其他DTO)为派生源通过外键关系不断关联多个BaseDTO的数据结构。VO用于在视图层与前端之间进行数据传输往往被当做HTTP API的返回值、或读方案的返回值使用由服务端返回至前端。注意VO不能作为RPC的返回值。
- **代码产物和修改建议**
- **结构定义**
* **生成产物:** 在controller层生成一个Java类
* **命名规则:** 类名以Vo结尾
* **职责:** 表达VO的数据结构
* **类路径:** 位于 ```**.entrance.web.vo``` 包路径下
* **唯一标识符位置:** 其对应的唯一标志在类注解@AutoGenerated中指定,uuid规则: ${VO在TOCO中的uuid}|VO|DEFINITION
- **Converter**
* **生成产物:** 在controller层生成一个Java类(**有派生源**的VO才有Converter)和基类
* **命名规则:** 实现类名以Converter结尾(${VoName}Converter)基类名以BaseConverter结尾(${VoName}BaseConverter)
* **类路径:** 位于 ```**.entrance.web.converter``` 包路径下
* **职责:** 把DTO转换成VOConverter中包含2种convert方法1.基础convert方法从DTO转换为VO仅转换结构方法命名为convertTo${VoName}、convertTo${VoName}List、convertTo${VoName}Map其中**Map转换方法**为底层批量方法单个和列表convert方法都通过**调用Map方法**来实现;2.带数据拼装逻辑的convert方法内部会调用基础convert方法从DTO转换为VO然后再根据外键获取拼装最终数据方法命名为convertAndAssembleData、convertAndAssembleDataList)
* **唯一标识符位置:**
* 实现类Converter其对应的唯一标志在类注解@AutoGenerated中指定,uuid规则: ${VO在TOCO中的uuid}|VO|CONVERTER
* 基类BaseConverter其对应的唯一标志在类注解@AutoGenerated中指定,uuid规则: ${DTO在TOCO中的uuid}|DTO|BASE_CONVERTER
* **例子:**
* 如UserDetailVo、UserDetailVoConverter包含convertToUserDetailVo、convertToUserDetailVoList、convertToUserDetailVoMap、convertAndAssembleData、convertAndAssembleDataList方法
- **修改建议:**
- 建议在Converter中进行代码扩展不建议修改结构定义文件。其中VO的**自定义字段**由于不直接派生自DTO所以一般会对应取数逻辑代码。通常如果涉及到数据获取、计算和拼装批量处理的性能最好所以自定义字段对应的代码位置**必须**放在Converter的**Map**基础转换方法convertTo${VoName}Map中批量取数组装如UserVoConverter.convertToUserVoMap
#### **2.8 查询对象(WO)**
- **定义与用途:** 在TOCO中WO表达某个Entity为基本通过外键关系不断关联多个Entity的数据结构。WO还隐式表达了数据的取数拼装这种拼装符合外键关系. WO作为ReadPlan的查询上下文使用所以在创建ReadPlan之前需要先创建WO对象。在理解一个ReadPlan的语义的时候需要以WO作为上下文。
#### **2.9 读方案 (ReadPlan)**
- **定义与用途:** 在TOCO中读方案描述了一种数据库查询方案查询条件为一个面向对象的查询语句其中可以包含存在外键关系的多个实体的字段(如age=18 and name like #nameLike and school.name like #schoolNameLike其中以#开头的是自定义参数会自动生成一个QTO结构由查询调用方动态传入),结果为符合查询条件的**一种**DTO或VO列表。读方案内部会将该面向对象的查询条件转化为复杂的join sql语句来实现对数据库的查询以及返回的复杂DTO和VO数据的组装。读方案可以指定其分页方式不分页、页码分页、瀑布流分页以及是否生成计数方法(用于返回符合条件的记录数量)。
- **代码产物和修改建议**
- **Service**
* **生成产物:** 在Service层生成一个Java类
* **命名规则:** 类名以QtoService结尾(${ReadPlanName}QtoService)
* **类路径:** 位于 ```**.service.index.entity```包路径下
* **职责:** 提供查询入口返回符合查询条件的DTO或VO的id列表分页、全部、或则瀑布流,以及返回符合条件的总数。 在TOCO的读链路中数据查询分2步骤1. 获取符合查询条件的DTO或VO的id列表2. 根据id列表组装DTO或VO列表。
* **唯一标识符位置:** 其对应的唯一标志在类注解@AutoGenerated中指定uuid规则: ${ReadPlan在TOCO中的uuid}|QTO|SERVICE
- **查询传输对象(QTO)**
* **生成产物:** 在Service层生成一个Java类
* **命名规则:** 类名以Qto结尾(${ReadPlanName}Qto)
* **类路径:** 位于 ```**.persist.qto```包路径下
* **职责:** 读方案的查询参数结构,通常可作为API的参数API接收到参数后可直接透传给内部的RPC进行调用
* **唯一标识符位置:** 其对应的唯一标志在类注解@AutoGenerated中指定,uuid规则: ${ReadPlan在TOCO中的uuid}|QTO|DEFINITION
- **Dao**
- **生成产物:** 在Dao层生成一个Java类
- **命名规则:** 类名以Dao结尾(${ReadPlanName}Dao)
- **类路径:** 位于 ```**.persist.mapper```包路径下
- **职责:** 读方案对应的数据库查询方法
- **唯一标识符位置:** 其对应的唯一标志在类注解@AutoGenerated中指定,uuid规则: ${ReadPlan在TOCO中的uuid}|QTO|DAO
- **QueryExecutor**
- **生成产物** 对于返回**VO**的查询方案在controller层生成一个Java类
- **命名规则:** 类名以QueryExecutor结尾(${WritePlanName}QueryExecutor)
- **类路径:** 位于 ```**.entrance.web.query.executor```包路径下
- **职责:** 把QtoService返回的id数据转化成目标**VO**
- **QueryService**
- **生成产物** 对于返回**DTO**的查询方案在service层生成一个Java类
- **命名规则:** 类名以QueryService结尾(${WritePlanName}QueryService)
- **类路径:** 位于 ```**.service.index.entity```包路径下
- **职责:** 把QtoService返回的id数据转化成目标**DTO**
- **例子:**
* 根据用户名称查询用户列表返回UserDTO则生成UserNameQto、UserNameQtoService、UserNameQtoDao、UserNameQueryService; UserNameQueryService调用UserNameQtoServiceUserNameQtoService调用UserNameQtoDao
- **修改建议:**
- 如果有对结果的数据二次处理建议在QueryService和QueryExecutor中进行代码扩展不建议修改QTO文件
#### **2.10 查询传输对象(QTO)**
- **定义与用途:** 在TOCO中QTO为读方案的查询参数结构每个读方案会对应一个QTO写方案调用方按照QTO的结构向读方案生成的RPC方法传入需要查询的实体字段值完成对数据库的查询
- **如何创建/生成:** 在创建读方案后TOCO会自动生成QTO作为该读方案传入的查询参数结构无需单独创建
- **关键配置:** 名称(${ReadPlanNameQto},驼峰展示),查询字段列表(如idIsnameLike, schoolNameLike等)
- **与API的关系:** QTO通常可作为API的参数API接收到参数后可直接透传给内部的RPC进行调用
#### **2.11 写方案 (WritePlan)**
- **定义与用途:** TOCO针对写场景定义了一种写方案所有对数据库的写操作都只能通过写方案实现。写方案包含了对数据库表的写操作。每个写方案只能操作一个聚合内部的表同时对一个聚合内表的操作尽量合并至一个写方案中根据复用性、内聚性等方面具体情况具体分析。注意写方案可以一次操作聚合内的多张表如location和storey是同一个聚合并且location和storey是**1:N**关系location是父对象聚合根storey是子对象那么我们可以创建一个写方案同时更新单个聚合根location中的信息以及操作其下的子表storey**列表**信息如新增、删除、修改storey等也可以创建一个写方案单独更新单个子表storey对象信息。
- **代码产物和修改建议**
- **Service:**
* **生成产物:** 在对应的聚合服务BoService里生成一个函数
* **函数命名规则:** 和写方案同名
* **职责:** 按需对入参进行转换调用BaseBOService里的函数完成对聚合对象的操作, 实现对数据库的写操作;
* **BoService的类路径:** ```**.service```
* **唯一标识符位置:** 其对应的标识符在函数的注解@AutoGenerated中指定, uuid规则: ${WritePlan在TOCO中的uuid}
- **BaseBoService**
- **生成产物:** 在对应的聚合的BaseBoService里生成一系列函数根据入参完成对聚合对象的变更
- **职责** 增对每个实体的生成增删改的函数,并且根据参数的结构以及聚合的结构,构建嵌套的调用逻辑,完成对一个聚合对象的变更,记录并且返回对应的变更情况
- **类路径:** ```**.service.base```
- **BTO (业务变更传输对象)**
* **生成产物:** 一个Java类以内部类的方式表示层级结构
* **命名规则:** 一个Bto结尾(${WritePlanName}Bto驼峰展示)
* **类路径:** 位于```**.service.bto```包路径下
* **职责:** 在**TOCO**中BTO为写方案的参数结构每个写方案会对应一个BTO写方案调用方按照BTO的结构向写方案生成的RPC方法传入需要查询的实体字段值完成对数据库的变更
* **唯一标识符位置:** 其对应的唯一标识符在类注解@AutoGenerated中指定, uuid规则: ${WritePlan在TOCO中的uuid}|BTO|DEFINITION
- **例子:**
- 创建用户以及用户设置的写方案create_user_and_setting生成CreateUserAndSettingBto, 在用户的聚合(UserBO)对应的UserBOService中生成函数createUserAndSetting该函数调用BaseUserBOService中生成的createUserAndSetting, 其中在BaseUserBOService中还生成了createUser和createSetting的函数, 一起完成了用户的创建和设置创建的逻辑。
- **修改建议:**
- 不能修改BaseBoService中的函数不建议修改BTO文件。建议在BOService中进行手动代码扩展处理可能被复用的修改前后的逻辑如修改数据库的前后值对比、或常被复用的校验逻辑业务不变性校验逻辑除外、需要经常在一个事务内执行的其他写操作等。
#### **2.12 业务变更传输对象(BTO)**
- **定义与用途:** 在TOCO中BTO为写方案自动生成的参数结构每个写方案会生成一个BTO。BTO为写方案选定的操作实体根据关系形成的树形集合最外层为聚合根。写方案调用方按照BTO的结构向写方案生成的RPC方法传入需要操作的实体字段值完成对数据库的写操作
- **与API的关系:** BTO通常可作为API的参数API接收到参数后可直接透传给内部的RPC进行调用
#### **2.13 服务层方法 (RPC)**
- **定义与用途:** 在TOCO中RPC为服务层的方法。RPC按照可见性可以分为两种一种是公开RPC可以被其他模块订阅订阅后可以通过RPC适配器进行调用另一种是非公开RPC只能被当前模块调用。非公开RPC可以被公开从而被其他模块订阅并调用
- **代码产物和修改建议**
- **生成代码:** RPC会在service层中生成类文件及实现函数包含DTO自动生成的RPC如UserDtoService.getById或UserBaseDtoService.getById、读写方案自动生成的RPC如UserDtoQueryService.queryByListQto、UserBOService.createUser、自定义RPC如UserCustomService.customMethod。特别注意公开的RPC才可被其他模块使用RPC被订阅后会生成RpcAdapter适配器其他模块通过RpcAdapter才可调用该方法。如Order模块订阅了User模块的UserDtoService.getById则会在Order模块中生成UserDtoServiceInOrderRpcAdapter.getById方法Order模块中的代码必须通过@Resource private UserDtoServiceInOrderRpcAdapter userDtoServiceInOrderRpcAdapter;注入适配器后才可进行方法调用
- **修改建议:** 建议修改RPC方法不建议修改RPC方法签名、适配器中的内容
#### **2.14 应用程序接口 (API)**
- **定义与用途:** 在TOCO中API用于定义对外暴露的HTTP接口
- **代码产物和修改建议**
- **生成代码:** API会在entrance层生成Controller以及对应的API方法
- **修改建议:** 建议修改API方法的实现内容不建议修改API方法签名、URI
### **3 生成代码产物补充说明**
- **3.1.1 支持的语言/框架**
Java、SpringBoot、MyBatis-plus(读)、Hibernate(写),具体的项目架构如下
```
TOCO生成的项目是一个多模块的SpringBoot项目,包括主模块和子模块
|──main_module
│ ├── common # 项目级别公共的基础模块
│ │ ├──config/ # 中间件配置
│ │ ├──constants/ # 项目级别常量
│ │ ├──enums/ # 项目级别枚举
│ │ ├──redis/ # Redis配置
│ │ ├──response/ # 返回结果封装
│ │ └──utils/ # 项目级别工具类
└── └── entrance/ # 项目入口
│ └──AppApplication.java # 项目启动类
└── modules # 子模块列表
└── module1/ # 子模块1
├── common/
│ ├──constants/ # 模块常量
│ ├──utils/ #模块级别工具类
│ └──enums/ # 枚举
├── entrance/
│ ├── controller/ # api 定义
│ ├──converter/ # 把DTO转化成VO
│ ├──vo/ # VO结构定义
│ └── query/ # 把读方案返回的数据转成成VO
│ ├── assembler/ # VO的数据填充
│ ├── collector/ # 读方案返回的id数据展开成完成对象数据
│ └── executor/ # 调用Service的度方案实现同时调用collector和assembler返回最终的VO
├── manager/ # Dto的查询接口定义
│ ├── bo/ # 聚合对象定义
│ ├── dto/ # 数据传输对象定义以及RPC引用的外模块的DTO定义
│ ├── converter/ # 复杂Dto非BaseDto)组装
│ ├── facade/ # 调用其他模块的RPC适配器包含RpcAdapter如UserDtoServiceInMeetingRpcAdapter表示从meeting模块调用user模块中方法
│ └── impl/ # Dto的查询接口的实现
├── persist/
│ ├── dos/ # 数据库单表结构的映射
│ ├── qto/ # 读方案的数据库查询实现
│ └── mapper/ # MyBatis的Mapper定义
└── service/ # BoService包含某个聚合下所有写方案生成的方法、 DtoService包含DTO生成的预定义方法
├── bto/ # 写方案入参的定义
├── converter/ # 对返回的BaseDto按需进行二次扩展
├── query/ # 查询方案的service层入口调用persist层的查询实现
└── base/ # 每个BoService对应的基类
在一个子模块的内它的依赖层级为entrance -> service -> manager -> persist, 同时各个层都依赖 common
```
- **3.1.2 特殊注解及含义**
TOC自动生成的类和方法会带有@AutoGenerated注解注解中有2个属性:locked为boolean类型如果locked=true则代表该文件或方法不建议修改;uuid为String类型表示该类或方法的唯一标识如果uuid中包含|字符则说明该uuid为特殊格式由不同类型的数据拼装而成(见**[3.2 设计元素到代码的映射规则及修改建议]**中每种设计元素的代码说明)。
### 4. 本地代码阅读和编写指南
#### 4.1 代码阅读
- 根据**设计元素到代码的映射规则及修改建议**在约读代码的时候你可以识别出对应的TOCO设计元素通过工具获取TOCO设计元素信息辅助理解代码语义特别是对于ReadPlanWritePlan的设计元素
- 读取类文件时应该同时读取继承的基类文件但注意不要去阅读BaseBOService里的代码**注意** 读取BO文件的时候一点要读取基类的文件避免字段没读全
- 不要去读VoConverter、DtoConverter、 BaseDtoConverter、BaseVoConverter
- 你无需关注BaseBoService里的代码
#### 4.2 代码编写
- 对于校验规则先判断是否为业务不变性规则如果是则将代码写在BO对象的聚合校验函数中即可实现校验功能不需要在Controller或Service中单独调用校验方法。聚合校验函数中适合做内存中数据的规则校验不适合做很重的外部存储数据的获取或RPC调用乐观锁字段由系统维护无需校验
- 需要着重考虑单一职责原则、复用性如Controller中更适合做参数校验及简单的不可复用的逻辑分支处理不适合实现复杂的或通用的业务逻辑
- 在循环中需要尽量避免执行调用数据库的操作,如查询数据库、写数据库等,尽量在循环外层先获取数据,在循环里面进行数据处理或读取
- 提高代码的可以读性复杂的业务逻辑需要拆解成多个函数一个函数的代码一般不要超过30行
- 如果代码中需要抛出异常则统一抛出IgnoredException(code, "message")异常如throw new IgnoredException(400, "xxx");code=400一般表示参数错误code=500一般表示处理出现错误。注意IgnoredException属于已有的包com.vs.ox.common.exception需要import com.vs.ox.common.exception.IgnoredException;
- 写代码时请注意BOService一般是用于写QueryService一般是用于读
- 输出代码前请仔细检查是否有错误的import如果有则将其修正
- 对于无法识别或直接生成的参数和逻辑,请增加一个相关的//TODO注释把从需求中解析到的可能的处理逻辑以java伪代码的形式写在注释中
- BoService 函数中的 boResult.getRootBo() 一定存在不要添加判断null的情况的代码; 不要添加调用rootBo.persist()的代码该方法的触发由生成的代码负责在BoService的函数中不要修改和注销系统生成的代码通过/** This block is generated by vs **/注释标注部分)
- 在函数中的不同片段逻辑,使用 {} 标注分块,附上注释,提升代码的可读性
- 以准确性作为第一优先级(不产生编译错误),不要直接生成不存在的函数、字段的调用; 如果逻辑上必须依赖,可以使用注释来表达
- 写代码时,如果发现有用户指定的上下文,则优先判断是否有可用的代码;如果用户有编写代码的特殊要求,则优先满足用户需求;如果前面已经有过规划信息,则尽量按照之前的规划来做,比如业务不变性的分析等
- 对于写服务的代码插入遵循如下规则: 1、 controller里插入入参的校验部分逻辑和参数重组逻辑 2、其他的逻辑在主BoService的主函数里为了增加代码可读性可以在BoService里新增函数
- 请在最后对所有你新增或修改的代码进行一次review重点关注是否存在编译错误代码可读性是否需要对大的函数进行拆分重构