组件公共域检测Skill component-common-domain-detection

本技能用于识别跨组件的重复域功能,检测共享类,分析合并可行性,并建议合并机会以减少代码重复、提高软件可维护性和优化架构。关键词:组件分析、公共域检测、代码重复、合并规划、软件架构、耦合评估。

架构设计 0 次安装 0 次浏览 更新于 3/15/2026

name: component-common-domain-detection description: 识别跨组件的重复域功能并建议合并机会。使用时机:查找公共域逻辑、检测重复功能、分析共享类、计划组件合并,或当用户询问公共组件、重复代码或域合并时。

公共域组件检测

本技能识别跨多个组件重复的公共域功能,并建议合并机会以减少重复和提高可维护性。

如何使用

快速开始

请求分析您的代码库:

  • “查找跨组件的公共域功能”
  • “识别应合并的重复域逻辑”
  • “检测跨多个组件使用的共享类”
  • “分析公共组件的合并机会”

使用示例

示例1:查找公共功能

用户:“查找跨组件的公共域功能”

技能将:
1. 扫描组件命名空间以查找公共模式
2. 检测跨组件使用的共享类
3. 识别重复域逻辑
4. 分析合并的耦合影响
5. 建议合并机会

示例2:检测重复通知逻辑

用户:“是否有多个通知组件应合并?”

技能将:
1. 查找所有与通知相关的组件名称
2. 分析其功能和依赖关系
3. 计算合并后的耦合影响
4. 推荐合并方法

示例3:分析共享类

用户:“查找跨多个组件共享的类”

技能将:
1. 识别被多个组件导入/使用的类
2. 分类为域功能与基础设施功能
3. 建议合并或共享库方法
4. 评估对耦合的影响

分步流程

  1. 扫描组件:识别具有公共命名空间模式的组件
  2. 检测共享代码:查找跨组件使用的类/文件
  3. 分析功能:确定功能是否真正公共
  4. 评估耦合:计算合并前的耦合影响
  5. 推荐操作:建议合并或共享库方法

何时使用

在以下情况应用此技能:

  • 在识别和调整组件后(模式1)
  • 在展平组件前(模式3)
  • 计划减少代码重复时
  • 分析代码库中的共享域逻辑时
  • 准备组件合并时
  • 识别共享服务或库候选时

核心概念

域功能与基础设施功能

域功能(合并候选):

  • 业务处理逻辑(通知、验证、审计、格式化)
  • 对某些过程公共,而非所有
  • 示例:客户通知、票务审计、数据验证

基础设施功能(通常不在此合并):

  • 操作关注点(日志记录、指标、安全)
  • 对所有过程公共
  • 示例:日志记录、身份验证、数据库连接

公共域模式

公共域功能常出现为:

  1. 命名空间模式:组件以相同叶节点结尾

    • *.notification*.audit*.validation*.formatting
    • 示例:TicketNotificationBillingNotificationSurveyNotification
  2. 共享类:多个组件使用相同的类

    • 示例:5个不同组件使用SMTPConnection
    • 示例:多个域组件使用AuditLogger
  3. 相似功能:不同组件执行相似任务

    • 示例:多个组件发送电子邮件,略有变化
    • 示例:多个组件写入审计日志

合并方法

共享服务

  • 公共功能成为独立服务
  • 其他组件调用此服务
  • 适用于:频繁更改的逻辑、复杂操作

共享库

  • 公共代码打包为库(JAR、DLL、npm包)
  • 组件导入并使用库
  • 适用于:稳定功能、简单工具

组件合并

  • 将多个组件合并为一个
  • 适用于:高度相关功能、低耦合影响

分析流程

阶段1:识别公共命名空间模式

扫描组件命名空间以查找公共叶节点名称:

  1. 提取叶节点自所有组件命名空间

    • 示例:services/billing/notificationnotification
    • 示例:services/ticket/notificationnotification
  2. 按公共叶节点分组

    • 查找具有相同叶节点名称的组件
    • 示例:所有以.notification结尾的组件
  3. 过滤基础设施模式

    • 排除:.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:检测共享类

查找跨多个组件使用的类/文件:

  1. 扫描每个组件的导入/依赖

    • 跟踪哪些类从何处导入
    • 注意被多个组件使用的类
  2. 识别共享类

    • 被2个以上组件导入的类
    • 排除基础设施类(Logger、Config等)
  3. 分类为域与基础设施

    • 域:业务逻辑类(SMTPConnection、AuditLogger)
    • 基础设施:技术工具(Logger、DatabaseConnection)

示例输出

## 找到的共享类

**域类**:

- `SMTPConnection` - 被5个组件使用(与通知相关)
- `AuditLogger` - 被8个组件使用(与审计相关)
- `DataFormatter` - 被3个组件使用(与格式化相关)

**基础设施类**(从合并中排除):

- `Logger` - 被所有组件使用(基础设施)
- `Config` - 被所有组件使用(基础设施)

阶段3:分析功能相似性

对于每组公共组件:

  1. 检查功能

    • 读取每个组件的源代码
    • 识别每个组件做什么
    • 注意相似性和差异
  2. 评估合并可行性

    • 差异是否微小(可配置)?
    • 差异是否可以抽象化?
    • 功能是否真正相同?
  3. 计算耦合影响

    • 统计合并前的传入依赖(传入耦合)
    • 估计合并后的传入依赖
    • 比较总耦合水平

示例分析

## 功能分析

**通知组件**:

- CustomerNotification:发送账单通知
- TicketNotification:发送票务分配通知
- SurveyNotification:发送调查邮件

**相似性**:所有都向客户发送邮件
**差异**:邮件内容/模板、触发条件

**合并可行性**:✅ 高

- 差异在于内容,而非机制
- 可以通过模板/上下文抽象化

阶段4:评估耦合影响

在建议合并前,分析耦合:

  1. 计算当前耦合

    • 统计使用每个通知组件的组件数量
    • 求和总传入依赖
  2. 估计合并后耦合

    • 统计将使用合并后组件的组件数量
    • 与当前总数比较
  3. 评估耦合增加

    • 合并后组件是否过于耦合?
    • 是否创建了瓶颈?
    • 耦合增加是否可以接受?

示例耦合分析

## 耦合影响分析

**合并前**:

- 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(通常为基础设施)
  • 不同上下文:名称相同,业务意义不同
  • 高耦合风险:合并会创建瓶颈

后续步骤

识别公共域组件后:

  1. 应用展平组件模式 - 移除孤立类
  2. 应用确定组件依赖模式 - 分析耦合
  3. 创建组件域 - 将组件分组到域中
  4. 计划合并 - 执行合并推荐

注意事项

  • 公共域功能不同于基础设施功能
  • 合并减少重复但可能增加耦合
  • 合并前始终分析耦合影响
  • 共享服务与共享库有不同的权衡
  • 如果减少耦合,某些重复是可接受的
  • 并非所有常见模式都应合并