name: component-identification-sizing description: 识别代码库中的架构组件并计算大小指标以用于分解规划。用于分析代码库结构、规划单体分解、识别过大组件、计算组件统计,或当用户询问组件分析、代码库大小或架构分解时。
组件识别与大小度量
本技能识别代码库中的架构组件(逻辑构建块)并计算大小指标以评估分解可行性和识别过大组件。
使用方法
快速开始
请求分析您的代码库:
- “识别并大小度量此代码库中的所有组件”
- “查找需要拆分的大组件”
- “为分解规划创建组件清单”
- “分析组件大小分布”
使用示例
示例1:完整分析
用户:“识别并大小度量此代码库中的所有组件”
本技能将:
1. 映射目录/命名空间结构
2. 识别所有组件(叶子节点)
3. 计算大小指标(语句数、文件数、百分比)
4. 生成组件清单表
5. 标记过大/过小组件
6. 提供建议
示例2:查找过大的组件
用户:“哪些组件过大?”
本技能将:
1. 计算均值和标准差
2. 识别大于2个标准差或大于10%阈值的组件
3. 分析大组件内的功能区域
4. 建议具体拆分方案及预估大小
示例3:组件大小分析
用户:“分析组件大小和分布”
本技能将:
1. 计算所有大小指标
2. 生成大小分布摘要
3. 识别异常值
4. 提供统计数据和推荐
分步过程
- 初始分析:从完整组件清单开始
- 识别问题:查找需要关注的组件
- 获取建议:请求可操作的拆分/合并建议
- 监控进度:随时间跟踪组件增长
使用时机
应用此技能于:
- 开始单体分解工作
- 评估代码库结构和组织
- 识别过大或过小的组件
- 为迁移规划创建组件清单
- 分析跨组件的代码分布
- 准备基于组件的分解模式
核心概念
组件定义
组件是架构构建块,具有:
- 明确角色和责任
- 由命名空间、包结构或目录路径识别
- 包含分组的源代码文件(类、函数、模块)
- 执行特定业务或基础设施功能
关键规则:组件通过目录/命名空间结构中的叶子节点识别。如果命名空间扩展(例如,从services/billing扩展到services/billing/payment),父节点成为子域,而非组件。
大小指标
语句数(非代码行数):
- 计数以分号或换行符终止的可执行语句
- 比代码行数更准确地进行大小比较
- 考虑代码复杂性,而非格式
组件大小指标:
- 代码库百分比:组件语句数 / 总语句数
- 文件数:组件中的源文件数量
- 标准差:与平均组件大小的距离
分析过程
阶段1:识别组件
扫描代码库目录结构:
-
映射目录/命名空间结构
- 对于Node.js:
services/、routes/、models/、utils/ - 对于Java:包结构(如
com.company.domain.service) - 对于Python:模块路径(如
app/billing/payment)
- 对于Node.js:
-
识别叶子节点
- 组件是包含源文件的最深层目录
- 例如:
services/BillingService/是组件 - 例如:
services/BillingService/payment/扩展它,使BillingService成为子域
-
创建组件清单
- 列出每个组件及其命名空间/路径
- 注意任何父命名空间(子域)
阶段2:计算大小指标
对于每个组件:
-
计数语句数
- 解析组件目录中的源文件
- 计数可执行语句(非注释、空行或单独声明)
- 汇总组件中所有文件的语句数
-
计数文件数
- 总源文件(
.js、.ts、.java、.py等) - 排除测试文件、配置文件、文档
- 总源文件(
-
计算百分比
component_percent = (component_statements / total_statements) * 100 -
计算统计
- 平均组件大小:
total_statements / number_of_components - 标准差:
sqrt(sum((size - mean)^2) / (n - 1)) - 组件的偏差:
(component_size - mean) / std_dev
- 平均组件大小:
阶段3:识别大小问题
过大组件(拆分候选):
- 超过总代码库30%(对于少于10个组件的小应用)
- 超过总代码库10%(对于多于20个组件的大应用)
- 超过平均以上2个标准差
- 包含多个不同功能区域
过小组件(合并候选):
- 小于总代码库1%(可能过于细化)
- 低于平均以下1个标准差
- 仅包含少量文件,功能最小
适当大小组件:
- 距离平均在1-2个标准差内
- 代表单一、内聚的功能区域
- 适合应用大小的百分比
输出格式
组件清单表
## 组件清单
| 组件名称 | 命名空间/路径 | 语句数 | 文件数 | 百分比 | 状态 |
| --------------- | ---------------------------- | ---------- | ----- | ------- | ------------ |
| Billing Payment | services/BillingService | 4,312 | 23 | 5% | ✅ 正常 |
| Reporting | services/ReportingService | 27,765 | 162 | 33% | ⚠️ 过大 |
| Notification | services/NotificationService | 1,433 | 7 | 2% | ✅ 正常 |
状态图例:
- ✅ 正常:大小适当(距离平均在1-2个标准差内)
- ⚠️ 过大:超过大小阈值或大于平均以上2个标准差
- 🔍 过小:小于总代码库1%或低于平均以下1个标准差
大小分析摘要
## 大小分析摘要
**总组件数**:18
**总语句数**:82,931
**平均组件大小**:4,607语句数
**标准差**:5,234语句数
**过大组件**(>2个标准差或>10%):
- Reporting(33% - 27,765语句数) - 考虑拆分为:
- Ticket Reports
- Expert Reports
- Financial Reports
**适当大小组件**(距离平均在1-2个标准差内):
- Billing Payment(5%)
- Customer Profile(5%)
- Ticket Assignment(9%)
**过小组件**(<1个标准差):
- Login(2% - 1,865语句数) - 考虑与Authentication合并
组件大小分布
## 组件大小分布
组件大小分布(按代码库百分比)
[如果可能,提供视觉表示或直方图]
最大:████████████████████████████████████ 33%(Reporting)
████████ 9%(Ticket Assign)
██████ 8%(Ticket)
██████ 6%(Expert Profile)
█████ 5%(Billing Payment)
████ 4%(Billing History)
...
推荐
## 推荐
### 高优先级:拆分大组件
**Reporting组件**(占代码库33%):
- **当前**:单组件,27,765语句数
- **问题**:过大,包含多个功能区域
- **推荐**:拆分为:
1. Reporting Shared(通用工具)
2. Ticket Reports(票据相关报告)
3. Expert Reports(专家相关报告)
4. Financial Reports(财务报告)
- **预期结果**:每个组件约占代码库7-9%
### 中优先级:审查小组件
**Login组件**(占代码库2%):
- **当前**:1,865语句数,3个文件
- **考虑**:如果与更广泛身份验证相关,可能过于细化
- **推荐**:评估是否应与Authentication/User组件合并
### 低优先级:监控适当大小组件
大多数组件大小适当。在分解过程中继续监控。
分析检查表
组件识别:
- [ ] 映射所有目录/命名空间结构
- [ ] 识别叶子节点(组件)与父节点(子域)
- [ ] 创建完整组件清单
- [ ] 记录每个组件的命名空间/路径
大小计算:
- [ ] 为每个组件计数语句数(非代码行数)
- [ ] 计数源文件数(排除测试/配置)
- [ ] 计算总代码库百分比
- [ ] 计算均值和标准差
大小评估:
- [ ] 识别过大组件(>阈值或>2个标准差)
- [ ] 识别过小组件(<1%或<1个标准差)
- [ ] 标记用于拆分或合并的组件
- [ ] 记录大小分布
推荐:
- [ ] 为过大组件建议拆分方案
- [ ] 为过小组件建议合并方案
- [ ] 按影响优先级排序推荐
- [ ] 创建重构的架构故事
实施说明
对于Node.js/Express应用
组件通常在:
services/- 业务逻辑组件routes/- API端点组件models/- 数据模型组件utils/- 工具组件middleware/- 中间件组件
组件识别示例:
services/
├── BillingService/ ← 组件(叶子节点)
│ ├── index.js
│ └── BillingService.js
├── CustomerService/ ← 组件(叶子节点)
│ └── CustomerService.js
└── NotificationService/ ← 组件(叶子节点)
└── NotificationService.js
对于Java应用
组件通过包结构识别:
com.company.domain.service- 服务组件com.company.domain.model- 模型组件com.company.domain.repository- 仓库组件
组件识别示例:
com.company.billing.payment ← 组件(叶子包)
com.company.billing.history ← 组件(叶子包)
com.company.billing ← 子域(payment/history的父节点)
语句计数
JavaScript/TypeScript:
- 计数以
;或换行符终止的语句 - 包括:赋值、函数调用、返回、条件语句、循环
- 排除:注释、空行、无赋值的声明
Java:
- 计数以
;终止的语句 - 包括:方法调用、赋值、返回、条件语句
- 排除:类/接口声明、注释、空行
Python:
- 计数可执行语句(非注释或空行)
- 包括:赋值、函数调用、返回、条件语句
- 排除:文档字符串、注释、空行
适应度函数
识别和大小度量组件后,创建自动化检查:
组件大小阈值
// 如果任何组件超过代码库10%,则告警
function checkComponentSize(components, threshold = 0.1) {
const totalStatements = components.reduce((sum, c) => sum + c.statements, 0)
return components
.filter((c) => c.statements / totalStatements > threshold)
.map((c) => ({
component: c.name,
percent: ((c.statements / totalStatements) * 100).toFixed(1),
issue: '超过大小阈值',
}))
}
标准差检查
// 如果组件大于平均以上2个标准差,则告警
function checkStandardDeviation(components) {
const sizes = components.map((c) => c.statements)
const mean = sizes.reduce((a, b) => a + b, 0) / sizes.length
const stdDev = Math.sqrt(sizes.reduce((sum, size) => sum + Math.pow(size - mean, 2), 0) / (sizes.length - 1))
return components
.filter((c) => Math.abs(c.statements - mean) > 2 * stdDev)
.map((c) => ({
component: c.name,
deviation: ((c.statements - mean) / stdDev).toFixed(2),
issue: '大于平均以上2个标准差',
}))
}
最佳实践
要做 ✅
- 使用语句数,非代码行数
- 仅将叶子节点识别为组件
- 计算百分比和标准差
- 设置阈值时考虑应用大小
- 记录每个组件的命名空间/路径
- 如果可能,创建视觉大小分布
避免 ❌
- 不要在组件大小中包含测试文件
- 不要将父目录视为组件
- 不要在不考虑应用大小的情况下使用固定阈值
- 不要忽略小组件(可能需要合并)
- 不要跳过标准差计算
- 不要在同一分析中混合基础设施和域组件
后续步骤
完成组件识别和大小度量后:
- 应用收集公共域组件模式 - 识别重复功能
- 应用扁平化组件模式 - 移除根命名空间中的孤儿类
- 应用确定组件依赖模式 - 分析组件间耦合
- 创建组件域 - 将组件分组到逻辑域中
注意事项
- 组件大小阈值因应用大小而异
- 小应用(<10个组件):30%阈值可能合适
- 大应用(>20个组件):10%阈值更合适
- 标准差比固定百分比更可靠
- 适当大小组件距离平均在1-2个标准差内
- 过大组件通常包含多个可拆分的功能区域