更新 llms-full.txt

This commit is contained in:
ycl
2025-06-22 16:58:06 +08:00
parent 3cdc037fd9
commit 33b9144c06

View File

@@ -463,9 +463,130 @@ DateTime endTime //会议结束时间
* 如UserDetailVo、UserDetailVoConverter包含convertToUserDetailVo、convertToUserDetailVoList、convertToUserDetailVoMap、convertAndAssembleData、convertAndAssembleDataList方法 * 如UserDetailVo、UserDetailVoConverter包含convertToUserDetailVo、convertToUserDetailVoList、convertToUserDetailVoMap、convertAndAssembleData、convertAndAssembleDataList方法
- **修改建议:** - **修改建议:**
- 建议在Converter中进行代码扩展不建议修改结构定义文件。其中VO的**自定义字段**由于不直接派生自DTO所以一般会对应取数逻辑代码。通常如果涉及到数据获取、计算和拼装批量处理的性能最好所以自定义字段对应的代码位置**必须**放在Converter的**Map**基础转换方法convertTo${VoName}Map中批量取数组装如UserVoConverter.convertToUserVoMap - 建议在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.8 读方案 (ReadPlan)** - **查询对象案设计元素的表达**
- 以json格式表达json schema 定义如下
```json
{
"type": "object","description": "查询对象定义", "required": ["name","fromEntity"],
"properties": {
"name": {"type": "string", "description": "查询对象名称用英语表达单词之间下划线分割长度补超过32个字符"},
"uuid": {"type": "string", "description": "查询对象uuid, 在更新的时候必须传递(只有根节点必须传递),创建的时候不传递"},
"moduleName": {"type": "string", "description": "查询对象所属模块名称,在创建的时候必须传递"},
"fromEntity": {"type": "string", "description": "查询对象对应的实体"},
"expandList": {
"type": "array", "description": "正向扩展列表",
"items":
{
"type": "object","description": "正向扩展字段定义","required": ["field","wo","fieldName"],
"properties": {
"field": {"type": "string", "description": "指定fromEntity的扩展字段必须是fromEntity的外键字段"},
"wo": {"$ref": "#"},
"fieldName": {"type": "string", "description": "扩展出来的字段名称"}
}
}
},
"reverseExpandList": {
"type": "array", "description": "反向扩展列表",
"items":
{
"type": "object","description": "反向扩展字段定义","required": ["field","wo","fieldName"],
"properties": {
"field": {"type": "string", "description": "指定fromEntity的扩展字段必须是fromEntity的外键字段"},
"wo": {"$ref": "#"},
"fieldName": {"type": "string", "description": "扩展出来的字段名称"}
}
}
}
}
}
```
- **如何创建/生成:**
- **关键配置:** Wo中的字段分为三种a.继承Entity的字段和Entity的字段类型一样b.扩展字段含正向替换和反向注入字段类型为WO或List<WO>;
- **字段扩展方式:**TOCO定义了一个WO组装方法适用于WO通过外键关系替换/注入对应Entity的信息对象化表达有外键关系的Entity信息。只要存在外键关系且满足以下条件即可扩展a.对于正向替换当前实体存在指向其他实体的外键字段b.对于反向注入:其他实体存在指向当前实体的外键字段。
例如有两个Entity
```
MeetingRoom{ //会议室
Long id;// 会议室id,主键
String name;// 会议室名称
}
Meeting { //会议
Long id;// 会议id,主键
Long roomid; //占用的会议室id到MeetingRoom的外键n:1关系
Long backupRoomid; //备用的会议室id到MeetingRoom的外键n:1关系
String title; //会议标题
DateTime startTime //会议开始时间
DateTime endTime //会议结束时间
}
```
其中Meeting和MeetingRoom是n:1关系。即多个会议室会占用同一个会议室。
当组装对象以某Entity为根时那么首先它将拥有和该Entity一样的数据结构并将通过下面的“正向替换”“反向注入”的行为递归的将多个互相之间有外键关系的Entity的信息组装到该组装对象中。
定义“正向替换”这个行为,选定一个表,这张表存在到另外一张表的一个或多个外键。选择和需求相关的具体的外键属性,将该外键属性替换为另一张表为根的组装对象。这样就可以获取基于某些外键且包含另一张表更详细的属性数据。
例如需要会议和其占用会议室时将Meeting表中的roomid外键替换为以MeetingRoom为根的组装对象而backupRoomid对应的候选会议室具体信息和本需求无关不做任何替换。如下
```
MeetingWithRoomWo {
Long id;// 会议id
MeetingRoomWo room { //正向替换该会议用的会议室信息,是一个以会议室为根的对象
Long id; //会议室ID
String name;// 会议室名称
}
Long backupRoomid; // 不做变化
String title; //会议标题
DateTime startTime //会议开始时间
DateTime endTime //会议结束时间
}
```
又例如需要会议和其候选会议室时将Meeting表中的backupRoomid进行正向替换。
又例如需要会议且即需要其占用会议室也需要候选会议室时将Meeting表中的roomidbackupRoomid都进行正向替换。
同时TOCO还定义了“反向注入”这个行为选定一个表如果有另外的表到前表有外键选择和需求相关的具体的外键属性在选定表中增加一个以另外表为根的组合对象(当外键关系是1:1时)或者组合对象的列表(当外键关系是n:1时)。需求是“获取会议室和占用它的会议信息”需要选定MeetingRoom那么基于另外的表Meeting中存在字段roomid为到MeetingRoom的n:1关系外键。可以将List<MeetingBaseDto>反向注入到MeetingRoom中最终生成一个以Meeting为根的组装对象生成
```
MeetingRoomWithMeetingWo {
Long id;// 会议室id
String name;// 会议室名称
List<MeetingBaseWo> meetingList { //反向注入的用该会议室的会议信息,是以会议为根的对象
Long id;// 会议id
String title; //会议标题
DateTime startTime //会议开始时间
DateTime endTime //会议结束时间
}
}
```
这种“正向替换”和“反向注入”可以按需递归调用去将多个互相之间有外键关系的对象组装成最终对象。例如还有另外一张表MeetingAgenda到Meeting有n:1的外键,那么如果我要去组装以Meeting开始包含MeetingRoom, MeetingAgenda的查询对象首先发现MeetingRoom是可以正向扩展到Meeting的并且可以反向注入MeetingAgenda
- meeting_with_room_and_agenda_wo
```json
{
"wo": {
"uuid": null,
"name": "meeting_with_room_and_agenda_wo",
"description": "会议详情,包含会议室信息,以及其中的会议列表",
"fromEntity": "meeting",
"expandList": [
{
"field": "room_id",
"fieldName": "meeting_room",
"wo": {
"name": "meeting_room_wo",
"fromEntity": "meeting_room",
"description": "会议室信息"
}
}
],
"reverseExpandList": [
{
"field":"meeting_id",
"filedName": "meeting_agenda_list",
"wo": {
"fromEntity": "meeting_agenda",
"name": "meeting_agenda_wo",
"description": "会议议程信息"
}
}
]
}
}
```
#### **2.9 读方案 (ReadPlan)**
- **定义与用途:** 在TOCO中读方案描述了一种数据库查询方案查询条件为一个面向对象的查询语句其中可以包含存在外键关系的多个实体的字段(如age=18 and name like #nameLike and school.name like #schoolNameLike其中以#开头的是自定义参数会自动生成一个QTO结构由查询调用方动态传入),结果为符合查询条件的**一种**DTO或VO列表。读方案内部会将该面向对象的查询条件转化为复杂的join sql语句来实现对数据库的查询以及返回的复杂DTO和VO数据的组装。读方案可以指定其分页方式不分页、页码分页、瀑布流分页以及是否生成计数方法(用于返回符合条件的记录数量)。 - **定义与用途:** 在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获取流程**),不建议使用读方案。非主键查询或多条件查询建议使用读方案。 - **使用建议:** 如果查询条件只有主键则建议使用预定义的getBy${PrimaryKey}或getBy${PrimaryKey}s方法来获取DTO参照DTO的**预定义方法**或VO参照**复杂嵌套VO获取流程**),不建议使用读方案。非主键查询或多条件查询建议使用读方案。
- **关键配置:** 名称(小写字母+下划线不要以read_plan结尾)、返回结构(DTO/VO一个读方案**不能**同时返回多种DTO或VO)、查询条件的自然语言描述、是否生成计数方法、排序字段(如果选择不分页,则不需要) - **关键配置:** 名称(小写字母+下划线不要以read_plan结尾)、返回结构(DTO/VO一个读方案**不能**同时返回多种DTO或VO)、查询条件的自然语言描述、是否生成计数方法、排序字段(如果选择不分页,则不需要)
@@ -676,7 +797,7 @@ DateTime endTime //会议结束时间
* **生成产物:** 在Service层生成一个Java类 * **生成产物:** 在Service层生成一个Java类
* **命名规则:** 类名以Qto结尾(${ReadPlanName}Qto) * **命名规则:** 类名以Qto结尾(${ReadPlanName}Qto)
* **类路径:** 位于 ```**.persist.qto```包路径下 * **类路径:** 位于 ```**.persist.qto```包路径下
* **职责:** 读方案的查询参数结构 * **职责:** 读方案的查询参数结构,通常可作为API的参数API接收到参数后可直接透传给内部的RPC进行调用
* **唯一标识符位置:** 其对应的唯一标志在类注解@AutoGenerated中指定,uuid规则: ${ReadPlan在TOCO中的uuid}|QTO|DEFINITION * **唯一标识符位置:** 其对应的唯一标志在类注解@AutoGenerated中指定,uuid规则: ${ReadPlan在TOCO中的uuid}|QTO|DEFINITION
- **Dao** - **Dao**
- **生成产物:** 在Dao层生成一个Java类 - **生成产物:** 在Dao层生成一个Java类
@@ -698,12 +819,12 @@ DateTime endTime //会议结束时间
* 根据用户名称查询用户列表返回UserDTO则生成UserNameQto、UserNameQtoService、UserNameQtoDao、UserNameQueryService; UserNameQueryService调用UserNameQtoServiceUserNameQtoService调用UserNameQtoDao * 根据用户名称查询用户列表返回UserDTO则生成UserNameQto、UserNameQtoService、UserNameQtoDao、UserNameQueryService; UserNameQueryService调用UserNameQtoServiceUserNameQtoService调用UserNameQtoDao
- **修改建议:** - **修改建议:**
- 如果有对结果的数据二次处理建议在QueryService和QueryExecutor中进行代码扩展不建议修改QTO文件 - 如果有对结果的数据二次处理建议在QueryService和QueryExecutor中进行代码扩展不建议修改QTO文件
#### **2.9 查询传输对象(QTO)** #### **2.10 查询传输对象(QTO)**
- **定义与用途:** 在TOCO中QTO为读方案的查询参数结构每个读方案会对应一个QTO写方案调用方按照QTO的结构向读方案生成的RPC方法传入需要查询的实体字段值完成对数据库的查询 - **定义与用途:** 在TOCO中QTO为读方案的查询参数结构每个读方案会对应一个QTO写方案调用方按照QTO的结构向读方案生成的RPC方法传入需要查询的实体字段值完成对数据库的查询
- **如何创建/生成:** 在创建读方案后TOCO会自动生成QTO作为该读方案传入的查询参数结构无需单独创建 - **如何创建/生成:** 在创建读方案后TOCO会自动生成QTO作为该读方案传入的查询参数结构无需单独创建
- **关键配置:** 名称(${ReadPlanNameQto},驼峰展示),查询字段列表(如idIsnameLike, schoolNameLike等) - **关键配置:** 名称(${ReadPlanNameQto},驼峰展示),查询字段列表(如idIsnameLike, schoolNameLike等)
- **与API的关系:** QTO通常可作为API的参数API接收到参数后可直接透传给内部的RPC进行调用 - **与API的关系:** QTO通常可作为API的参数API接收到参数后可直接透传给内部的RPC进行调用
#### **2.10 写方案 (WritePlan)** #### **2.11 写方案 (WritePlan)**
- **定义与用途:** TOCO针对写场景定义了一种写方案所有对数据库的写操作都只能通过写方案实现。写方案包含了对数据库表的写操作。每个写方案只能操作一个聚合内部的表同时对一个聚合内表的操作尽量合并至一个写方案中根据复用性、内聚性等方面具体情况具体分析。注意写方案可以一次操作聚合内的多张表如location和storey是同一个聚合并且location和storey是**1:N**关系location是父对象聚合根storey是子对象那么我们可以创建一个写方案同时更新单个聚合根location中的信息以及操作其下的子表storey**列表**信息如新增、删除、修改storey等也可以创建一个写方案单独更新单个子表storey对象信息。 - **定义与用途:** 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(批量更新**列表**数据,根据传入的列表数据,一条一条执行) - **关键配置:** 名称(小写字母+下划线不要以write_plan结尾)操作的聚合聚合内的实体和字段对每个实体的操作类型CREATE创建**单个**实体UPDATE(更新**单个**实体), DELETE(删除**单个**实体), CREATE_ON_DUPLICATE_UPDATE(创建或者更新**单个**实体),FULL_MERGE( 批量更新**列表**数据根据传入的列表数据一条一条执行CREATE_ON_DUPLICATE_UPDATE的操作并且删除掉老的列表中不在传入列表数据中的部分), PARTIAL_MERGE(批量更新**列表**数据,根据传入的列表数据,一条一条执行)
- **与RPC的关系:** 对于每一个写方案TOCO会自动生成一个RPC方法其参数为写方案对应的BTO返回值为本次操作的聚合根实体的主键值内部只实现了对当前聚合的数据库操作 - **与RPC的关系:** 对于每一个写方案TOCO会自动生成一个RPC方法其参数为写方案对应的BTO返回值为本次操作的聚合根实体的主键值内部只实现了对当前聚合的数据库操作
@@ -844,7 +965,7 @@ DateTime endTime //会议结束时间
- **修改建议:** - **修改建议:**
- 不能修改BaseBoService中的函数不建议修改BTO文件。建议在BOService中进行手动代码扩展处理可能被复用的修改前后的逻辑如修改数据库的前后值对比、或常被复用的校验逻辑业务不变性校验逻辑除外、需要经常在一个事务内执行的其他写操作等。 - 不能修改BaseBoService中的函数不建议修改BTO文件。建议在BOService中进行手动代码扩展处理可能被复用的修改前后的逻辑如修改数据库的前后值对比、或常被复用的校验逻辑业务不变性校验逻辑除外、需要经常在一个事务内执行的其他写操作等。
#### **2.11 业务变更传输对象(BTO)** #### **2.12 业务变更传输对象(BTO)**
- **定义与用途:** 在TOCO中BTO为写方案自动生成的参数结构每个写方案会生成一个BTO。BTO为写方案选定的操作实体根据关系形成的树形集合最外层为聚合根。写方案调用方按照BTO的结构向写方案生成的RPC方法传入需要操作的实体字段值完成对数据库的写操作 - **定义与用途:** 在TOCO中BTO为写方案自动生成的参数结构每个写方案会生成一个BTO。BTO为写方案选定的操作实体根据关系形成的树形集合最外层为聚合根。写方案调用方按照BTO的结构向写方案生成的RPC方法传入需要操作的实体字段值完成对数据库的写操作
- **如何创建/生成:** 在创建写方案后TOCO会自动生成一个BTO作为该写方案传入的参数结构无需通过TOCO创建。 - **如何创建/生成:** 在创建写方案后TOCO会自动生成一个BTO作为该写方案传入的参数结构无需通过TOCO创建。
- **关键配置:** 名称(${WritePlanName}Bto驼峰展示嵌套的树形实体和字段列表BTO内部的字段全部都来自Entity。以下为一个示例 - **关键配置:** 名称(${WritePlanName}Bto驼峰展示嵌套的树形实体和字段列表BTO内部的字段全部都来自Entity。以下为一个示例
@@ -859,7 +980,7 @@ DateTime endTime //会议结束时间
} }
``` ```
- **与API的关系:** BTO通常可作为API的参数API接收到参数后可直接透传给内部的RPC进行调用 - **与API的关系:** BTO通常可作为API的参数API接收到参数后可直接透传给内部的RPC进行调用
#### **2.12 服务层方法 (RPC)** #### **2.13 服务层方法 (RPC)**
- **定义与用途:** 在TOCO中RPC为服务层的方法。RPC按照可见性可以分为两种一种是公开RPC可以被其他模块订阅订阅后可以通过RPC适配器进行调用另一种是非公开RPC只能被当前模块调用。非公开RPC可以被公开从而被其他模块订阅并调用 - **定义与用途:** 在TOCO中RPC为服务层的方法。RPC按照可见性可以分为两种一种是公开RPC可以被其他模块订阅订阅后可以通过RPC适配器进行调用另一种是非公开RPC只能被当前模块调用。非公开RPC可以被公开从而被其他模块订阅并调用
- **如何创建/生成:** RPC有4种创建方式a.DTO创建后会自动创建RPCRPC的公开性与DTO的公开性保持一致b.返回DTO的读方案会根据分页情况、以及是否生成计数函数的配置自动生成非公开的RPC c.写方案创建后会自动生成非公开的RPC d.如果上述三种RPC无法满足需求则可以通过TOCO创建自定义RPC完整指定功能需指定具体的参数和返回值以及公开性等。 - **如何创建/生成:** RPC有4种创建方式a.DTO创建后会自动创建RPCRPC的公开性与DTO的公开性保持一致b.返回DTO的读方案会根据分页情况、以及是否生成计数函数的配置自动生成非公开的RPC c.写方案创建后会自动生成非公开的RPC d.如果上述三种RPC无法满足需求则可以通过TOCO创建自定义RPC完整指定功能需指定具体的参数和返回值以及公开性等。
- **优先复用:** 当用户需要创建一个RPC时如果用户有明确要求创建的方式则按照用户的要求来创建。如果没有明确要求则通常先判断是否可以通过创建读方案、写方案、DTO来使TOCO自动创建出对应的RPC最后再考虑通过TOCO创建自定义RPC - **优先复用:** 当用户需要创建一个RPC时如果用户有明确要求创建的方式则按照用户的要求来创建。如果没有明确要求则通常先判断是否可以通过创建读方案、写方案、DTO来使TOCO自动创建出对应的RPC最后再考虑通过TOCO创建自定义RPC
@@ -891,7 +1012,7 @@ requestParams为请求参数列表response为返回结构requestParams中
- **代码产物和修改建议** - **代码产物和修改建议**
- **生成代码:** 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会在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方法签名、适配器中的内容 - **修改建议:** 建议修改RPC方法不建议修改RPC方法签名、适配器中的内容
#### **2.13 应用程序接口 (API)** #### **2.14 应用程序接口 (API)**
- **定义与用途:** 在TOCO中API用于定义对外暴露的HTTP接口 - **定义与用途:** 在TOCO中API用于定义对外暴露的HTTP接口
- **如何创建/生成:** API一般为通过TOCO创建需指定具体的参数和返回值等 - **如何创建/生成:** API一般为通过TOCO创建需指定具体的参数和返回值等
- **关键配置:** uri(加粗展示,一般为/api/${moduleName}/xxx如/api/user/create。如果用户有特殊命名规则的话以用户要求为准)、类名(以Controller结尾)、方法名、请求参数、返回值 - **关键配置:** uri(加粗展示,一般为/api/${moduleName}/xxx如/api/user/create。如果用户有特殊命名规则的话以用户要求为准)、类名(以Controller结尾)、方法名、请求参数、返回值
@@ -927,7 +1048,7 @@ requestParams为请求参数列表response为返回结构requestParams中
- **代码产物和修改建议** - **代码产物和修改建议**
- **生成代码:** API会在entrance层生成Controller以及对应的API方法 - **生成代码:** API会在entrance层生成Controller以及对应的API方法
- **修改建议:** 建议修改API方法的实现内容不建议修改API方法签名、URI - **修改建议:** 建议修改API方法的实现内容不建议修改API方法签名、URI
#### **2.14 流程服务FunctionFlow)** #### **2.15 流程服务FunctionFlow)**
- **定义与用途:** TOCO针对复杂业务拆解定义了流程服务把一个复杂的业务过程根据业务逻辑的内聚性合并逻辑功能把流程分解成流程节点最终构造出一个类似工作流的逻辑流程最终实现复杂业务流程分解提升代码的可维护性。TOCO内嵌了流程引擎在Function_Flow生成代码后可以在流程引擎中执行 - **定义与用途:** TOCO针对复杂业务拆解定义了流程服务把一个复杂的业务过程根据业务逻辑的内聚性合并逻辑功能把流程分解成流程节点最终构造出一个类似工作流的逻辑流程最终实现复杂业务流程分解提升代码的可维护性。TOCO内嵌了流程引擎在Function_Flow生成代码后可以在流程引擎中执行
- **何时使用:** - **何时使用:**
- 如果一个API/RPC中涉及的写服务超过3个则推荐使用流程服务 - 如果一个API/RPC中涉及的写服务超过3个则推荐使用流程服务