Update llms-full.txt

This commit is contained in:
2025-06-18 15:28:20 +08:00
parent f838eb24e2
commit bd1492b3d4

View File

@@ -1,30 +1,31 @@
# TOCO知识库
## **1. TOCO 平台概览:**
## TOCO知识库
### **1. TOCO 平台概览:**
- **1.1 平台简介:** TOCO是一款重视软件设计及核心代码自动生成的专业研发平台。其基于DDD、分层设计、CQRS等经典研发理论从数据库到API全部覆盖可显著提升开发设计和编程效率帮助开发团队实现更高的质量和生产力
- **1.2 核心价值/目标用户:** 从软件工程理论出发,提供软件设计能力,设计结果可直接转换为标准格式的代码,提升编码一致性及效率
- **1.3 主要特性概览:** 可视化设计、模型关联、多人协作、代码生成器等
## **2. TOCO 设计元素:**
### **2.1 模块 (Module)**
### **2. TOCO 设计元素:**
#### **2.1 模块 (Module)**
- **定义与用途:** 在TOCO中我们将系统领域细分为具体的模块映射为Java工程中的module。这些模块代表了系统的叶子子域每个模块负责特定的功能。模块划分有助于系统的可维护性和可扩展性并能提高开发效率和代码质量
- **关键配置:** 名称(小写英文字母+下划线如meeting,user_detail,禁止加任何固定后缀),描述
- **与其他元素关系:** 下面的每种设计元素都属于一个模块
### **2.2 枚举 (Enum)**
#### **2.2 枚举 (Enum)**
- **定义与用途:** Enum用来表达一些常量值的集合可被其他模块使用可被用来做为字段的类型
- **关键属性/配置:** 名称(以_enum结尾),枚举值列表(全大写字母+下划线)
### **2.3 值对象 (Eo)**
#### **2.3 值对象 (Eo)**
- **定义与用途:** EO为一种POJO对象结构可被其他模块使用可被用来做为实体字段的类型
- **关键属性/配置:** 名称(以_eo结尾)字段列表。EO的字段类型只能为基本类型含List、EO、Enum其他类型不允许
### **2.4 实体关系 (ER / Entity)**
#### **2.4 实体关系 (ER / Entity)**
- **定义与用途:** 实体及其关系。一个实体一般对应一个数据库表,关系为实体间的外键依赖关系
- **关键属性/配置:** 实体中包含名称、字段、字段类型、主键、索引等关系分为1:1和1:N关系
- **与其他元素关系:** 实体关系是聚合的基础也是DTO和VO的派生基础
### **2.5 聚合对象 (BO/业务对象)**
#### **2.5 聚合对象 (BO/业务对象)**
- **定义与用途:** 在TOCO中聚合对象是对一组密切关联的实体的封装。聚合对象从单一实体开始这个实体我们称为聚合根通过实体间关系不断的顺序将其他实体按层级关系组装进这个聚合对象。聚合对象可以按实体表达为树形结构。聚合对象提供了这组实体的内存一致性视图提供数据操作入口。由于写操作的内聚性聚合对象只能在单一模块中组合而且一个实体只能属于一个对象。同样如果有实体不在任何一个聚合对象中TOCO将无法提供与之相关的写方法。
- **包含元素:** 聚合对象包括聚合根及其聚合下的其他子实体对象例如商品聚合ProductBO中商品基本信息实体是ProductBO的聚合根商品SKU实体、商品库存实体是ProductBO的子聚合对象。
- **关键配置:** 名称(${EntityName驼峰}BO结尾如StaffBO),聚合根实体,聚合子对象实体。每个聚合必须包含一个聚合根
- **与其他元素关系:** 聚合是写方案的基础
### **2.6 数据传输对象 (DTO)**
#### **2.6 数据传输对象 (DTO)**
- **定义与用途:** 在TOCO中DTO表达某个Entity为基本通过外键关系不断关联多个Entity的数据结构。DTO还隐式表达了数据的取数拼装这种拼装符合外键关系。往往被当做RPC的返回值、或读方案的返回值使用不建议把DTO作为入参。注意DTO不能作为HTTP API的返回值。DTO分为BaseDTO和普通DTOBaseDTO派生自Entity包含Entity的所有字段每个Entity有且仅有一个BaseDTO普通DTO派生自BaseDTO包含BaseDTO的所有字段且可以增加扩展字段或自定义字段
- **如何创建/生成:** 对于每个EntityTOCO会自动生成一个BaseDTO命名为${Entity名字}BaseDto如UserBaseDto该BaseDTO包含了Entity的全部字段。除了BaseDTO其他的DTO均需要手动以BaseDTO为根来创建。在TOCO中必须要先判断需要的DTO是否为BaseDTO如果是BaseDTO则可通过Entity名称获取BaseDTO如果不是BaseDTO则需要通过DTO要表达的信息来创建DTO会议及其议程信息。
- **关键配置:** 名称(BaseDTO以BaseDto结尾其他DTO以Dto结尾)、根Entity、字段列表。DTO中的字段分为三种a.继承Entity或BaseDTO的字段和Entity及BaseDTO的字段类型一样b.扩展字段含正向替换和反向注入字段类型为DTO或List<DTO>;c.自定义字段类型为基本类型、Eo、Enum、DTO类型。BaseDTO中一般包含Entity的全部字段,DTO中一般包含BaseDTO中的全部字段不进行字段裁剪可以根据外键关系扩展其他Entity(详见**字段扩展方式**)在明确无法扩展外部Entity的情况下可增加对应的自定义字段。
@@ -90,7 +91,7 @@ DateTime endTime //会议结束时间
- b. 如果通过其他复杂查询条件则可以采用第2种方式
注意判断使用哪种方式时,只能根据查询条件判断是否使用读方案,绝对禁止使用返回值是否需要数据拼装来判断!**如果现实中的代码和TOCO中的步骤有冲突时只能使用TOCO的定义**
### **2.7 视图对象 (VO)**
#### **2.7 视图对象 (VO)**
- **定义与用途:** 在TOCO中VO表达某个BaseDTO(如果用户指明派生源也可使用其他DTO)为派生源通过外键关系不断关联多个BaseDTO的数据结构。VO用于在视图层与前端之间进行数据传输往往被当做HTTP API的返回值、或读方案的返回值使用由服务端返回至前端。注意VO不能作为RPC的返回值。
- **关键配置:** 名称(以Vo结尾)、根Entity、派生源、字段列表。VO中的字段分为三种a.继承DTO的字段和DTO的字段类型一样b.扩展字段含正向替换和反向注入字段类型为VO或List<VO>;c.自定义字段类型为基本类型或VO类型。VO中的字段来源于DTO可以根据页面需要进行裁剪可以根据外键关系扩展其他BaseDto(详见**字段扩展方式**)。如果在派生源中没有合适字段且明确无法通过外键扩展外部BaseDto的情况下可增加对应的自定义字段
- **与DTO的区别 (在TOCO语境下): **DTO用于服务层传输通常作为RPC的返回值与数据模型更近复用性较强VO用于视图层传输通常作为API的返回值与UI展示更为接近复用性较弱。
@@ -156,7 +157,7 @@ DateTime endTime //会议结束时间
- c. 如果用户上下文中有指定的返回DTO的读方案符合条件则使用第2种否则使用第3种
注意判断使用哪种方式时,只能根据查询条件判断是否使用读方案,绝对禁止使用返回值是否需要数据拼装来判断!**如果现实中的代码编写方式和TOCO中的步骤有冲突时只能使用TOCO的定义**
### **2.8 读方案 (ReadPlan)**
#### **2.8 读方案 (ReadPlan)**
- **定义与用途:** 在TOCO中读方案描述了一种数据库查询方案查询条件为一个面向对象的查询语句其中可以包含存在外键关系的多个实体的字段(如age=18 and name like #nameLike and school.name like #schoolNameLike其中以#开头的是自定义参数会自动生成一个QTO结构由查询调用方动态传入),结果为符合查询条件的**一种**DTO或VO列表。读方案内部会将该面向对象的查询条件转化为复杂的join sql语句来实现对数据库的查询以及返回的复杂DTO和VO数据的组装。读方案可以指定其分页方式不分页、页码分页、瀑布流分页以及是否生成计数方法(用于返回符合条件的记录数量)。
- **使用建议:** 如果查询条件只有主键则建议使用预定义的getBy${PrimaryKey}或getBy${PrimaryKey}s方法来获取DTO参照DTO的**预定义方法**或VO参照**复杂嵌套VO获取流程**),不建议使用读方案。非主键查询或多条件查询建议使用读方案。
- **关键配置:** 名称(小写字母+下划线不要以read_plan结尾)、返回结构(DTO/VO一个读方案**不能**同时返回多种DTO或VO)、查询条件的自然语言描述、是否生成计数方法、排序字段(如果选择不分页,则不需要)
@@ -356,12 +357,12 @@ DateTime endTime //会议结束时间
}
}
```
### **2.9 查询传输对象(QTO)**
#### **2.9 查询传输对象(QTO)**
- **定义与用途:** 在TOCO中QTO为读方案的查询参数结构每个读方案会对应一个QTO写方案调用方按照QTO的结构向读方案生成的RPC方法传入需要查询的实体字段值完成对数据库的查询
- **如何创建/生成:** 在创建读方案后TOCO会自动生成QTO作为该读方案传入的查询参数结构无需单独创建
- **关键配置:** 名称(${ReadPlanNameQto},驼峰展示),查询字段列表(如idIsnameLike, schoolNameLike等)
- **与API的关系:** QTO通常可作为API的参数API接收到参数后可直接透传给内部的RPC进行调用
### **2.10 写方案 (WritePlan)**
#### **2.10 写方案 (WritePlan)**
- **定义与用途:** TOCO针对写场景定义了一种写方案所有对数据库的写操作都只能通过写方案实现。写方案包含了对数据库表的写操作。每个写方案只能操作一个聚合内部的表同时对一个聚合内表的操作尽量合并至一个写方案中根据复用性、内聚性等方面具体情况具体分析。注意写方案可以一次操作聚合内的多张表如location和storey是同一个聚合并且location和storey是**1:N**关系location是父对象聚合根storey是子对象那么我们可以创建一个写方案同时更新单个聚合根location中的信息以及操作其下的子表storey**列表**信息如新增、删除、修改storey等也可以创建一个写方案单独更新单个子表storey对象信息。
- **关键配置:** 名称(小写字母+下划线不要以write_plan结尾)操作的聚合聚合内的实体和字段对每个实体的操作类型CREATE创建**单个**实体UPDATE(更新**单个**实体), DELETE(删除**单个**实体), CREATE_ON_DUPLICATE_UPDATE(创建或者更新**单个**实体),FULL_MERGE( 批量更新**列表**数据根据传入的列表数据一条一条执行CREATE_ON_DUPLICATE_UPDATE的操作并且删除掉老的列表中不在传入列表数据中的部分), PARTIAL_MERGE(批量更新**列表**数据,根据传入的列表数据,一条一条执行)
- **与RPC的关系:** 对于每一个写方案TOCO会自动生成一个RPC方法其参数为写方案对应的BTO返回值为本次操作的聚合根实体的主键值内部只实现了对当前聚合的数据库操作
@@ -489,7 +490,7 @@ DateTime endTime //会议结束时间
]
}
```
### **2.11 业务变更传输对象(BTO)**
#### **2.11 业务变更传输对象(BTO)**
- **定义与用途:** 在TOCO中BTO为写方案自动生成的参数结构每个写方案会生成一个BTO。BTO为写方案选定的操作实体根据关系形成的树形集合最外层为聚合根。写方案调用方按照BTO的结构向写方案生成的RPC方法传入需要操作的实体字段值完成对数据库的写操作
- **如何创建/生成:** 在创建写方案后TOCO会自动生成一个BTO作为该写方案传入的参数结构无需通过TOCO创建。
- **关键配置:** 名称(${WritePlanName}Bto驼峰展示嵌套的树形实体和字段列表BTO内部的字段全部都来自Entity。以下为一个示例
@@ -504,7 +505,7 @@ DateTime endTime //会议结束时间
}
```
- **与API的关系:** BTO通常可作为API的参数API接收到参数后可直接透传给内部的RPC进行调用
### **2.12 服务层方法 (RPC)**
#### **2.12 服务层方法 (RPC)**
- **定义与用途:** 在TOCO中RPC为服务层的方法。RPC按照可见性可以分为两种一种是公开RPC可以被其他模块订阅订阅后可以通过RPC适配器进行调用另一种是非公开RPC只能被当前模块调用。非公开RPC可以被公开从而被其他模块订阅并调用
- **如何创建/生成:** RPC有4种创建方式a.DTO创建后会自动创建RPCRPC的公开性与DTO的公开性保持一致b.返回DTO的读方案会根据分页情况、以及是否生成计数函数的配置自动生成非公开的RPC c.写方案创建后会自动生成非公开的RPC d.如果上述三种RPC无法满足需求则可以通过TOCO创建自定义RPC完整指定功能需指定具体的参数和返回值以及公开性等。
- **优先复用:** 当用户需要创建一个RPC时如果用户有明确要求创建的方式则按照用户的要求来创建。如果没有明确要求则通常先判断是否可以通过创建读方案、写方案、DTO来使TOCO自动创建出对应的RPC最后再考虑通过TOCO创建自定义RPC
@@ -566,7 +567,7 @@ requestParams为请求参数列表response为返回结构requestParams中
```
结构中一些关键字段描述如下:
requestParams为请求参数列表response为返回结构requestParams中每个参数和response的结构相同其中name为参数名;type为参数类型参数类型取值范围为Boolean,String,Integer,Long,Float,Double,BigDecimal,Date,ByteArray,Enum,Eo,List,Vo,Qto,Bto,Void其中参数不能为Void如果不需要返回值则type设置为Voiddescription为描述uuid为参数对应类结构的UUID当type为Enum、Eo、Vo、Qto、Bto时包含该字段innerType为List内部类型当type为List时包含该字段innerUuid为List内部类结构的UUID当type为List且innerType为Enum、Eo、Vo、Qto、Bto时包含该字段。
### **2.14 流程服务Function_Flow)**
#### **2.14 流程服务Function_Flow)**
- **定义与用途:** TOCO针对复杂业务拆解定义了流程服务把一个复杂的业务过程根据业务逻辑的内聚性合并逻辑功能把流程分解成流程节点最终构造出一个类似工作流的逻辑流程最终实现复杂业务流程分解提升代码的可维护性。TOCO内嵌了流程引擎在Function_Flow生成代码后可以在流程引擎中执行
- **何时使用:**
- 如果一个API/RPC中涉及的写服务超过3个则推荐使用流程服务
@@ -651,16 +652,16 @@ requestParams为请求参数列表response为返回结构requestParams中
}
```
## **3. TOCO 代码生成说明**
### **3.1 生成代码产物说明**
### **3. TOCO 代码生成说明**
#### **3.1 生成代码产物说明**
- **3.1.1 支持的语言/框架**
Java、SpringBoot、MyBatis-plus(读)、Hibernate(写)
- **3.1.2 特殊注解及含义**
TOC自动生成的类和方法会带有@AutoGenerated注解注解中有2个属性:locked为boolean类型如果locked=true则代表该文件或方法不建议修改;uuid为String类型表示该类或方法的唯一标识如果uuid中包含|字符则说明该uuid为特殊格式由不同类型的数据拼装而成(见**[3.2 设计元素到代码的映射规则及修改建议]**中每种设计元素的代码说明)。
### **3.2 设计元素到代码的映射规则及修改建议**
#### 3.2.1 Module
#### **3.2 设计元素到代码的映射规则及修改建议**
##### 3.2.1 Module
- **生成代码:** 每个Module会单独生成一个Java Module项目路径/modules/模块名内部采用了entrance、service、manager、persist、common分层结构
#### 3.2.2 Enum
##### 3.2.2 Enum
* **生成产物**在common模块中生成一个Java类
* **职责:** 表达Enum的数据结构
* **命名规则**类名以Enum结尾
@@ -668,14 +669,14 @@ requestParams为请求参数列表response为返回结构requestParams中
* **唯一标识符位置:** 其对应的唯一标志在类注解@AutoGenerated中指定 ,uuid规则: ${Enum在TOCO中的uuid}|ENUM|DEFINITION
- **生成代码:** Enum会在common层生成Enum文件如StatusEnum
- **修改建议:** 不建议修改
#### 3.2.3 EO
##### 3.2.3 EO
* **生成产物**在persist层生成结构定义类文如AddressEo
* **职责:** 表达POJO数据结构
* **命名规则**类名以Eo结尾
* **类路径:** 位于 ```**.persist.eo``` 包路径下
* **唯一标识符位置:** 其对应的唯一标志在类注解@AutoGenerated中指定 ,uuid规则: ${Eo在TOCO中的uuid}|EO|DEFINITION
- **修改建议:** 不建议修改
#### 3.2.4 Entity
##### 3.2.4 Entity
- 结构定义
* **生成产物**Java类按照Mybatis-plus的要求生成
* **职责:** 按照Mybatis-plus的要求生成结构定义类文件
@@ -700,7 +701,7 @@ requestParams为请求参数列表response为返回结构requestParams中
* **类路径:** 位于 ```**.persist.mapper``` 包路径下
* **唯一标识符位置:** 其对应的唯一标志在类注解@AutoGenerated中指定 ,uuid规则: ${Entity在TOCO中的uuid}|ENTITY|DAO
- **修改建议:** 不建议修改
#### 3.2.5 业务对象 (BO)
##### 3.2.5 业务对象 (BO)
- 综述
- 业务对象包含多个Entity通过业务对象的嵌套组合表达了Entity之间的关系如果一个业务对象包含了子对象则会生成BO和BaseBO,BaseBO封装实体属性和关系子类留给业务扩展逻辑
如果是叶子节点不存在子对象的BO则直接生成BO类文件不生成BaseBO类文件
@@ -718,7 +719,7 @@ requestParams为请求参数列表response为返回结构requestParams中
* **类路径:** 位于 ```**.manager.bo``` 包路径下
* **唯一标识符位置:** 其对应的唯一标志在类注解@AutoGenerated中指定 ,uuid规则: ${Entity在TOCO中的uuid}|BO|DEFINITION
- **修改建议:** 建议修改BO中的validateAggregate或valid方法如果发现需求中有业务不变性校验;不建议修改检验方法以外的其他代码
#### 3.2.6 数据传输对象 (DTO)
##### 3.2.6 数据传输对象 (DTO)
- 结构定义
* **生成产物**一个Java类
* **职责:** 表达DTO的数据结构
@@ -743,7 +744,7 @@ requestParams为请求参数列表response为返回结构requestParams中
* 如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>)
#### 3.2.7 视图对象 (VO)
##### 3.2.7 视图对象 (VO)
- **结构定义**
* **生成产物:** 在controller层生成一个Java类
* **命名规则:** 类名以Vo结尾
@@ -762,7 +763,7 @@ requestParams为请求参数列表response为返回结构requestParams中
* 如UserDetailVo、UserDetailVoConverter包含convertToUserDetailVo、convertToUserDetailVoList、convertToUserDetailVoMap、convertAndAssembleData、convertAndAssembleDataList方法
- **修改建议:**
- 建议在Converter中进行代码扩展不建议修改结构定义文件。其中VO的**自定义字段**由于不直接派生自DTO所以一般会对应取数逻辑代码。通常如果涉及到数据获取、计算和拼装批量处理的性能最好所以自定义字段对应的代码位置**必须**放在Converter的**Map**基础转换方法convertTo${VoName}Map中批量取数组装如UserVoConverter.convertToUserVoMap
#### 3.2.8 读方案 (ReadPlan)
##### 3.2.8 读方案 (ReadPlan)
- **Service**
* **生成产物:** 在Service层生成一个Java类
* **命名规则:** 类名以QtoService结尾(${ReadPlanName}QtoService)
@@ -795,7 +796,7 @@ requestParams为请求参数列表response为返回结构requestParams中
* 根据用户名称查询用户列表返回UserDTO则生成UserNameQto、UserNameQtoService、UserNameQtoDao、UserNameQueryService; UserNameQueryService调用UserNameQtoServiceUserNameQtoService调用UserNameQtoDao
- **修改建议:**
- 如果有对结果的数据二次处理建议在QueryService和QueryExecutor中进行代码扩展不建议修改QTO文件
#### 3.2.9 写方案 (WritePlan)
##### 3.2.9 写方案 (WritePlan)
- **Service:**
* **生成产物:** 在对应的聚合服务BoService里生成一个函数
* **函数命名规则:** 和写方案同名
@@ -816,13 +817,13 @@ requestParams为请求参数列表response为返回结构requestParams中
- 创建用户以及用户设置的写方案create_user_and_setting生成CreateUserAndSettingBto, 在用户的聚合(UserBO)对应的UserBOService中生成函数createUserAndSetting该函数调用BaseUserBOService中生成的createUserAndSetting, 其中在BaseUserBOService中还生成了createUser和createSetting的函数, 一起完成了用户的创建和设置创建的逻辑。
- **修改建议:**
- 不能修改BaseBoService中的函数不建议修改BTO文件。建议在BOService中进行手动代码扩展处理可能被复用的修改前后的逻辑如修改数据库的前后值对比、或常被复用的校验逻辑业务不变性校验逻辑除外、需要经常在一个事务内执行的其他写操作等。
#### 3.2.10 RPC
##### 3.2.10 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方法签名、适配器中的内容
#### 3.2.11 API
##### 3.2.11 API
- **生成代码:** API会在entrance层生成Controller以及对应的API方法
- **修改建议:** 建议修改API方法的实现内容不建议修改API方法签名、URI
#### 3.2.12 流程服务(FunctionFlow)
##### 3.2.12 流程服务(FunctionFlow)
- **FlowConfig**
* **生成产物:** 每个模块在service层的生成一个Java类负责注册模块下的所有流程到执行器
* **命名规则:** 类名为${moduleName}FlowConfig
@@ -849,12 +850,33 @@ requestParams为请求参数列表response为返回结构requestParams中
- 用户登录在UserFlowService中生成一个函数invokeLoginFlow该函数通过流程框架根据流程定义调用LoginNodeLoginNode中封装了用户登录的逻辑LoginFlowContext中封装了用户登录的参数和结果。
- **修改建议:** 不修改 service 中的函数, 不修改FlowConfig, 可以修改FlowContext, 添加/修改出入参数, 修改FlowNode中的具体业务逻辑。
## 4. TOCO 最佳实践
### 4.1 设计分析结果应用(Design analysis results application):
### 4. TOCO 最佳实践
#### 4.1 设计分析结果应用(Design analysis results application):
在TOCO中设计分析(designAnalyze工具)的结果按照用户的要求或需求的复杂度分为2种你需要分辨流程分析的结果类型然后根据不同类型做出不同的后续工具调用规划:
- 1.**细节设计分析**:针对简单或短流程需求,会直接进行读写方案、接口等分析、代码编写等结果。此时需要根据工具规划后续的调用。
- 2.**流程拆解设计分析**:针对复杂需求,不会直接分析细节的设计元素,而是根据内聚、解耦、复用等原则,参考**流程服务Function_Flow)**对业务需求拆解为多个短流程并返回结果。后续需要针对整体的API的定义、流程服务定义、**所有**流程节点中涉及的**所有**DTO、VO、读写方案、RPC等来进行对应的工具调用。注意此时**必须**调用createFunctionFlow工具来创建流程服务。
### 4.2 为所有的写场景都创建写方案(Create WritePlan For All Write Scenarios):
#### 4.2 为所有的写场景都创建写方案(Create WritePlan For All Write Scenarios):
通常在分析业务需求时,需要分析出**所有**写数据的场景,并按照**聚合维度**进行分组,然后针对每个写场景**都需要**创建对应的写方案,不能有遗漏。写方案可以按需根据聚合进行合并。
### 4.3 接口参数类型和返回值选择(Interface Parameter & Return Type Definition):
#### 4.3 接口参数类型和返回值选择(Interface Parameter & Return Type Definition):
在做TOCO接口(API、RPC)设计时通常会先判断接口的主要功能是读数据库或写数据库并分析相关的读写方案以及对应的QTO和BTO。如果是读场景则参数会**优先使**用相关的QTO如果是写场景则参数会**优先**使用相关的BTO如果BTO和QTO无法满足要求则可以再增加基本类型或Enum、EO等类型参数。参数类型选择时必须遵循以下要求a.DTO、VO不能作为参数类型b.QTO、BTO不能作为返回值类型
### 5. 本地代码阅读和编写指南
#### 5.1 代码阅读
- 根据**设计元素到代码的映射规则及修改建议**在约读代码的时候你可以识别出对应的TOCO设计元素通过工具获取TOCO设计元素信息辅助理解代码语义特别是对于ReadPlanWritePlan的设计元素
- 读取类文件时应该同时读取继承的基类文件但注意不要去阅读BaseBOService里的代码
- 不要去读VoConverter、DtoConverter、 BaseDtoConverter、BaseVoConverter的代码
#### 5.2 代码编写
- 对于校验规则先判断是否为业务不变性规则如果是则将代码写在BO对象的聚合校验函数中即可实现校验功能不需要在Controller或Service中单独调用校验方法。聚合校验函数中适合做内存中数据的规则校验不适合做很重的外部存储数据的获取或RPC调用乐观锁字段由系统维护无需校验
- 需要着重考虑单一职责原则、复用性如Controller中更适合做参数校验及简单的不可复用的逻辑分支处理不适合实现复杂的或通用的业务逻辑
- 在循环中需要尽量避免执行调用数据库的操作,如查询数据库、写数据库等,尽量在循环外层先获取数据,在循环里面进行数据处理或读取
- 提高代码的可以读性复杂的业务逻辑需要拆解成多个函数一个函数的代码一般不要超过30行
- 如果代码中需要抛出异常则统一抛出IgnoredException(code, "message")异常如throw new IgnoredException(400, "xxx");code=400一般表示参数错误code=500一般表示处理出现错误。同时增加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重点关注是否存在编译错误代码可读性是否需要对大的函数进行拆分重构