name: component-common-domain-detection description: 识别跨组件的重复域功能并建议合并机会。使用时机:查找公共域逻辑、检测重复功能、分析共享类、计划组件合并,或当用户询问公共组件、重复代码或域合并时。
公共域组件检测
本技能识别跨多个组件重复的公共域功能,并建议合并机会以减少重复和提高可维护性。
如何使用
快速开始
请求分析您的代码库:
- “查找跨组件的公共域功能”
- “识别应合并的重复域逻辑”
- “检测跨多个组件使用的共享类”
- “分析公共组件的合并机会”
使用示例
示例1:查找公共功能
用户:“查找跨组件的公共域功能”
技能将:
1. 扫描组件命名空间以查找公共模式
2. 检测跨组件使用的共享类
3. 识别重复域逻辑
4. 分析合并的耦合影响
5. 建议合并机会
示例2:检测重复通知逻辑
用户:“是否有多个通知组件应合并?”
技能将:
1. 查找所有与通知相关的组件名称
2. 分析其功能和依赖关系
3. 计算合并后的耦合影响
4. 推荐合并方法
示例3:分析共享类
用户:“查找跨多个组件共享的类”
技能将:
1. 识别被多个组件导入/使用的类
2. 分类为域功能与基础设施功能
3. 建议合并或共享库方法
4. 评估对耦合的影响
分步流程
- 扫描组件:识别具有公共命名空间模式的组件
- 检测共享代码:查找跨组件使用的类/文件
- 分析功能:确定功能是否真正公共
- 评估耦合:计算合并前的耦合影响
- 推荐操作:建议合并或共享库方法
何时使用
在以下情况应用此技能:
- 在识别和调整组件后(模式1)
- 在展平组件前(模式3)
- 计划减少代码重复时
- 分析代码库中的共享域逻辑时
- 准备组件合并时
- 识别共享服务或库候选时
核心概念
域功能与基础设施功能
域功能(合并候选):
- 业务处理逻辑(通知、验证、审计、格式化)
- 对某些过程公共,而非所有
- 示例:客户通知、票务审计、数据验证
基础设施功能(通常不在此合并):
- 操作关注点(日志记录、指标、安全)
- 对所有过程公共
- 示例:日志记录、身份验证、数据库连接
公共域模式
公共域功能常出现为:
-
命名空间模式:组件以相同叶节点结尾
*.notification、*.audit、*.validation、*.formatting- 示例:
TicketNotification、BillingNotification、SurveyNotification
-
共享类:多个组件使用相同的类
- 示例:5个不同组件使用
SMTPConnection - 示例:多个域组件使用
AuditLogger
- 示例:5个不同组件使用
-
相似功能:不同组件执行相似任务
- 示例:多个组件发送电子邮件,略有变化
- 示例:多个组件写入审计日志
合并方法
共享服务:
- 公共功能成为独立服务
- 其他组件调用此服务
- 适用于:频繁更改的逻辑、复杂操作
共享库:
- 公共代码打包为库(JAR、DLL、npm包)
- 组件导入并使用库
- 适用于:稳定功能、简单工具
组件合并:
- 将多个组件合并为一个
- 适用于:高度相关功能、低耦合影响
分析流程
阶段1:识别公共命名空间模式
扫描组件命名空间以查找公共叶节点名称:
-
提取叶节点自所有组件命名空间
- 示例:
services/billing/notification→notification - 示例:
services/ticket/notification→notification
- 示例:
-
按公共叶节点分组
- 查找具有相同叶节点名称的组件
- 示例:所有以
.notification结尾的组件
-
过滤基础设施模式
- 排除:
.util、.helper、.common(通常为基础设施) - 聚焦:
.notification、.audit、.validation、.formatting
- 排除:
示例输出:
## 找到的公共命名空间模式
**通知组件**:
- services/customer/notification
- services/ticket/notification
- services/survey/notification
**审计组件**:
- services/billing/audit
- services/ticket/audit
- services/survey/audit
阶段2:检测共享类
查找跨多个组件使用的类/文件:
-
扫描每个组件的导入/依赖
- 跟踪哪些类从何处导入
- 注意被多个组件使用的类
-
识别共享类
- 被2个以上组件导入的类
- 排除基础设施类(Logger、Config等)
-
分类为域与基础设施
- 域:业务逻辑类(SMTPConnection、AuditLogger)
- 基础设施:技术工具(Logger、DatabaseConnection)
示例输出:
## 找到的共享类
**域类**:
- `SMTPConnection` - 被5个组件使用(与通知相关)
- `AuditLogger` - 被8个组件使用(与审计相关)
- `DataFormatter` - 被3个组件使用(与格式化相关)
**基础设施类**(从合并中排除):
- `Logger` - 被所有组件使用(基础设施)
- `Config` - 被所有组件使用(基础设施)
阶段3:分析功能相似性
对于每组公共组件:
-
检查功能
- 读取每个组件的源代码
- 识别每个组件做什么
- 注意相似性和差异
-
评估合并可行性
- 差异是否微小(可配置)?
- 差异是否可以抽象化?
- 功能是否真正相同?
-
计算耦合影响
- 统计合并前的传入依赖(传入耦合)
- 估计合并后的传入依赖
- 比较总耦合水平
示例分析:
## 功能分析
**通知组件**:
- CustomerNotification:发送账单通知
- TicketNotification:发送票务分配通知
- SurveyNotification:发送调查邮件
**相似性**:所有都向客户发送邮件
**差异**:邮件内容/模板、触发条件
**合并可行性**:✅ 高
- 差异在于内容,而非机制
- 可以通过模板/上下文抽象化
阶段4:评估耦合影响
在建议合并前,分析耦合:
-
计算当前耦合
- 统计使用每个通知组件的组件数量
- 求和总传入依赖
-
估计合并后耦合
- 统计将使用合并后组件的组件数量
- 与当前总数比较
-
评估耦合增加
- 合并后组件是否过于耦合?
- 是否创建了瓶颈?
- 耦合增加是否可以接受?
示例耦合分析:
## 耦合影响分析
**合并前**:
- CustomerNotification:被2个组件使用(CA = 2)
- TicketNotification:被2个组件使用(CA = 2)
- SurveyNotification:被1个组件使用(CA = 1)
- **总CA**:5
**合并后**:
- Notification:被5个组件使用(CA = 5)
- **总CA**:5(相同!)
**结论**:✅ 无耦合增加,安全合并
阶段5:推荐合并方法
基于分析,推荐方法:
共享服务(如果):
- 功能频繁更改
- 复杂操作
- 需要独立扩展
- 多个部署单元将使用它
共享库(如果):
- 稳定功能
- 简单工具
- 编译时依赖可接受
- 无需独立部署
组件合并(如果):
- 高度相关功能
- 低耦合影响
- 相同部署单元可接受
输出格式
公共域组件报告
## 找到的公共域组件
### 通知功能
**组件**:
- services/customer/notification (2% - 1,433语句)
- services/ticket/notification (2% - 1,765语句)
- services/survey/notification (2% - 1,299语句)
**共享类**:SMTPConnection(被所有3个使用)
**功能分析**:
- 所有都向客户发送邮件
- 差异:内容/模板、触发条件
- 合并可行性:✅ 高
**耦合分析**:
- 前:CA = 2 + 2 + 1 = 5
- 后:CA = 5(无增加)
- 结论:✅ 安全合并
**推荐**:合并为`services/notification`
- 方法:共享服务
- 预计大小:~4,500语句(代码库的5%)
- 好处:减少重复、更易维护
合并机会表
## 合并机会
| 公共功能 | 组件 | 当前 CA | 后 CA | 可行性 | 推荐 |
| --- | --- | --- | --- | --- | --- |
| 通知 | 3个组件 | 5 | 5 | ✅ 高 | 合并为共享服务 |
| 审计 | 3个组件 | 8 | 12 | ⚠️ 中等 | 合并,监控耦合 |
| 验证 | 2个组件 | 3 | 3 | ✅ 高 | 合并为共享库 |
详细合并计划
## 合并计划
### 优先级:高
**通知组件** → `services/notification`
**步骤**:
1. 创建新组件`services/notification`
2. 从3个组件移动公共功能
3. 创建内容/模板的抽象
4. 更新依赖组件以使用新服务
5. 移除旧通知组件
**预计影响**:
- 减少代码:约4,500语句合并
- 减少重复:3个组件→1个
- 耦合:无增加(CA保持5)
- 维护:更易维护单一组件
### 优先级:中等
**审计组件** → `services/audit`
**步骤**:
[类似格式]
**预计影响**:
- 耦合增加:CA 8→12(监控)
- 好处:减少重复
分析检查清单
公共模式检测:
- [ ] 扫描所有组件命名空间以查找公共叶节点
- [ ] 识别具有相同结尾名称的组件
- [ ] 过滤基础设施模式
- [ ] 分组相似组件
共享类检测:
- [ ] 扫描每个组件的导入/依赖
- [ ] 识别被多个组件使用的类
- [ ] 分类为域与基础设施
- [ ] 记录共享类使用情况
功能分析:
- [ ] 检查公共组件的源代码
- [ ] 识别相似性和差异
- [ ] 评估合并可行性
- [ ] 确定差异是否可以抽象化
耦合评估:
- [ ] 计算每个组件的当前耦合(CA)
- [ ] 估计合并后耦合
- [ ] 比较总耦合水平
- [ ] 评估耦合增加是否可接受
推荐:
- [ ] 建议合并方法(服务/库/合并)
- [ ] 按影响优先推荐
- [ ] 创建合并计划与步骤
- [ ] 估计预期好处和风险
实现说明
对于Node.js/Express应用
常见模式:
services/
├── CustomerService/
│ └── notification.js ← 常见模式
├── TicketService/
│ └── notification.js ← 常见模式
└── SurveyService/
└── notification.js ← 常见模式
共享类:
- 检查
require()语句 - 查找从其他组件导入的类
- 示例:
const SMTPConnection = require('../shared/SMTPConnection')
对于Java应用
常见模式:
com.company.billing.audit ← 常见模式
com.company.ticket.audit ← 常见模式
com.company.survey.audit ← 常见模式
共享类:
- 检查
import语句 - 查找公共包中的类
- 示例:
import com.company.shared.AuditLogger
检测策略
命名空间模式检测:
// 从命名空间提取叶节点
function extractLeafNode(namespace) {
const parts = namespace.split('/')
return parts[parts.length - 1]
}
// 按叶节点分组
function groupByLeafNode(components) {
const groups = {}
components.forEach((comp) => {
const leaf = extractLeafNode(comp.namespace)
if (!groups[leaf]) groups[leaf] = []
groups[leaf].push(comp)
})
return groups
}
共享类检测:
// 查找被多个组件使用的类
function findSharedClasses(components) {
const classUsage = {}
components.forEach((comp) => {
comp.imports.forEach((imp) => {
if (!classUsage[imp]) classUsage[imp] = []
classUsage[imp].push(comp.name)
})
})
return Object.entries(classUsage)
.filter(([cls, users]) => users.length > 1)
.map(([cls, users]) => ({ class: cls, usedBy: users }))
}
适应性函数
识别公共组件后,创建自动检查:
公共命名空间模式检测
// 如果创建了具有常见模式的新组件,则告警
function checkCommonPatterns(components, exclusionList = []) {
const leafNodes = {}
components.forEach((comp) => {
const leaf = extractLeafNode(comp.namespace)
if (!exclusionList.includes(leaf)) {
if (!leafNodes[leaf]) leafNodes[leaf] = []
leafNodes[leaf].push(comp.name)
}
})
return Object.entries(leafNodes)
.filter(([leaf, comps]) => comps.length > 1)
.map(([leaf, comps]) => ({
pattern: leaf,
components: comps,
suggestion: '考虑合并这些组件',
}))
}
共享类使用告警
// 如果类被多个组件使用,则告警
function checkSharedClasses(components, exclusionList = []) {
const classUsage = {}
components.forEach((comp) => {
comp.imports.forEach((imp) => {
if (!exclusionList.includes(imp)) {
if (!classUsage[imp]) classUsage[imp] = []
classUsage[imp].push(comp.name)
}
})
})
return Object.entries(classUsage)
.filter(([cls, users]) => users.length > 1)
.map(([cls, users]) => ({
class: cls,
usedBy: users,
suggestion: '考虑提取到共享组件或库',
}))
}
最佳实践
做 ✅
- 区分域与基础设施功能
- 在合并前分析耦合影响
- 考虑共享服务和共享库方法
- 查找命名空间模式和共享类
- 在合并前验证功能是否真正相似
- 计算前后耦合指标(CA)
不做 ❌
- 不要合并基础设施功能(单独处理)
- 不要不分析耦合影响就合并
- 不要假设所有常见模式都应合并
- 不要忽略功能差异
- 如果耦合增加过高,不要合并
- 不要在同一分析中混合域和基础设施
常见模式
高合并候选
- 通知:
*.notification、*.notify、*.email - 审计:
*.audit、*.auditing、*.log - 验证:
*.validation、*.validate、*.validator - 格式化:
*.format、*.formatter、*.formatting - 报告:
*.report、*.reporting(如果功能相似)
低合并候选
- 基础设施:
*.util、*.helper、*.common(通常为基础设施) - 不同上下文:名称相同,业务意义不同
- 高耦合风险:合并会创建瓶颈
后续步骤
识别公共域组件后:
- 应用展平组件模式 - 移除孤立类
- 应用确定组件依赖模式 - 分析耦合
- 创建组件域 - 将组件分组到域中
- 计划合并 - 执行合并推荐
注意事项
- 公共域功能不同于基础设施功能
- 合并减少重复但可能增加耦合
- 合并前始终分析耦合影响
- 共享服务与共享库有不同的权衡
- 如果减少耦合,某些重复是可接受的
- 并非所有常见模式都应合并