mcpField
C
component-flattening-analysis

component-flattening-analysis

github.com/tech-leads-club开发7.1k214 次安装3 天前更新
代码仓库

关于 component-flattening-analysis

component-flattening-analysis 是用于分析代码库组件层级的技能,重点查找根命名空间中的孤立类。它可绘制命名空间结构、提出或执行扁平化重构,并检查引用和测试。

主要功能

  1. 01映射命名空间与组件层级
  2. 02查找根命名空间中的孤立类
  3. 03比较合并、拆分和共享代码策略
  4. 04生成重构步骤与工作量估算
  5. 05更新引用并验证改动

适用场景

  1. 01审查代码库中的层级违规
  2. 02查找扩展根命名空间中的源文件
  3. 03规划组件合并或拆分
  4. 04重构命名空间并检查依赖引用

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/tech-leads-club/agent-skills --skill component-flattening-analysis

安装后在 Claude Code 中输入/component-flattening-analysis确认已加载。

附带文件QUICK-REFERENCE.mdREADME.md

详细介绍

组件扁平化分析

此技能可识别组件层级问题,并确保组件仅作为目录/命名空间结构中的叶节点存在,同时从根命名空间中移除孤立类。

使用方法

快速开始

请求分析您的代码库:

  • “查找根命名空间中的孤立类”
  • “扁平化组件层级”
  • “识别需要扁平化的组件”
  • “分析组件结构中的层级问题”
使用示例

示例 1:查找孤立类

User: "Find orphaned classes in root namespaces"

The skill will:
1. Scan component namespaces for hierarchy issues
2. Identify orphaned classes in root namespaces
3. Detect components built on top of other components
4. Suggest flattening strategies
5. Create refactoring plan

示例 2:扁平化组件

User: "Flatten component hierarchies in this codebase"

The skill will:
1. Identify components with hierarchy issues
2. Analyze orphaned classes
3. Suggest consolidation or splitting strategies
4. Create refactoring plan
5. Estimate effort

示例 3:组件结构分析

User: "Analyze component structure for hierarchy issues"

The skill will:
1. Map component namespace structure
2. Identify root namespaces with code
3. Find components built on components
4. Flag hierarchy violations
5. Provide recommendations
分步流程
  1. 扫描结构:梳理组件命名空间层级
  2. 识别问题:查找孤立类和组件嵌套
  3. 分析选项:确定扁平化策略(合并还是拆分)
  4. 制定计划:生成包含具体步骤的重构计划
  5. 执行:重构组件以移除层级结构

适用场景

在以下情况下使用此技能:

  • 收集常见领域组件之后(模式 2)
  • 确定组件依赖关系之前(模式 4)
  • 组件具有嵌套结构时
  • 查找根命名空间中的孤立类时
  • 准备进行领域分组时
  • 清理组件结构时
  • 确保组件仅作为叶节点存在时

核心概念

组件定义

在目录/命名空间结构中,组件对应一个叶节点:

  • 叶节点:包含源文件的最深层目录
  • 组件:叶节点命名空间中的源代码文件
  • 子域:已扩展的父命名空间

关键规则:组件仅作为叶节点存在。如果某个命名空间已扩展,那么它的父级就成为子域,而不是组件。

根命名空间

根命名空间是已扩展的命名空间节点:

  • 已扩展:在其下方添加了另一个命名空间节点
  • 示例:ss.survey 扩展为 ss.survey.templates
  • 结果:ss.survey 成为根命名空间(子域)
孤立类

孤立类是位于根命名空间中的源文件:

  • 位置:根命名空间(非叶节点)
  • 问题:没有与之关联的可定义组件
  • 解决方案:将其移至叶节点命名空间(组件)

示例:

ss.survey/              ← Root namespace (extended by .templates)
├── Survey.js           ← Orphaned class (in root namespace)
└── templates/          ← Component (leaf node)
    └── Template.js
扁平化策略

策略 1:向下合并

  • 将叶节点中的代码移入根命名空间
  • 使根命名空间成为组件
  • 示例:将 ss.survey.templates 移入 ss.survey

策略 2:向上拆分

  • 将根命名空间中的代码移入新的叶节点
  • 从根命名空间创建新组件
  • 示例:将 ss.survey 拆分为 ss.survey.create + ss.survey.process

策略 3:移动共享代码

  • 将共享代码移至专用组件
  • 创建 .shared 组件
  • 示例:将 ss.survey 中的共享代码移至 ss.survey.shared

分析流程

阶段 1:梳理组件结构

扫描目录/命名空间结构,以识别层级关系:

  1. 梳理命名空间树

    • 构建所有命名空间的树状结构
    • 识别父子关系
    • 标记叶节点(组件)
  2. 识别根命名空间

    • 找出已扩展的命名空间
    • 将其标记为根命名空间(子域)
    • 记录扩展这些命名空间的对象
  3. 定位源文件

    • 查找每个命名空间中的所有源文件
    • 将文件映射到其所在的命名空间
    • 识别位于根命名空间中的文件

结构映射示例:

## Component Structure Map

ss.survey/ ← 根命名空间(已扩展) ├── Survey.js ← 孤立类 ├── SurveyProcessor.js ← 孤立类 └── templates/ ← 组件(叶节点) ├── EmailTemplate.js └── SMSTemplate.js

ss.ticket/ ← 根命名空间(已扩展) ├── Ticket.js ← 孤立类 ├── assign/ ← 组件(叶节点) │ └── TicketAssign.js └── route/ ← 组件(叶节点) └── TicketRoute.js

第 2 阶段:识别孤立类

查找根命名空间中的源文件:

  1. 扫描根命名空间

    • 检查每个根命名空间中的源文件
    • 识别孤立文件
    • 统计每个根命名空间中的孤立文件数量
  2. 对孤立类分类

    • 共享代码:通用工具、接口、抽象类
    • 领域代码:应属于组件的业务逻辑
    • 混合:共享代码与领域代码的组合
  3. 评估影响

    • 有多少孤立文件?
    • 它们包含哪些功能?
    • 哪些组件依赖它们?

孤立类检测示例:

## Orphaned Classes Found

### Root Namespace: ss.survey

**Orphaned Files** (5 files):

- Survey.js (domain code - survey creation)
- SurveyProcessor.js (domain code - survey processing)
- SurveyValidator.js (shared code - validation)
- SurveyFormatter.js (shared code - formatting)
- SurveyConstants.js (shared code - constants)

**Classification**:

- Domain Code: 2 files (should be in components)
- Shared Code: 3 files (should be in .shared component)

**Dependencies**: Used by ss.survey.templates component
第 3 阶段:分析扁平化选项

为每个根命名空间确定最佳扁平化策略:

  1. 选项 1:向下整合

    • 将叶节点代码移入根命名空间
    • 使根命名空间成为组件
    • 适用情况:叶节点较小,且包含相关功能
  2. 选项 2:向上拆分

    • 将根命名空间代码移入新的叶节点
    • 从根命名空间创建多个组件
    • 适用情况:根命名空间包含不同的功能领域
  3. 选项 3:迁移共享代码

    • 将共享代码提取到 .shared 组件
    • 将领域代码保留在根命名空间中或进行拆分
    • 适用情况:根命名空间包含共享工具

扁平化分析示例:

## Flattening Options Analysis

### Root Namespace: ss.survey

**Current State**:

- Root namespace: 5 orphaned files
- Leaf component: ss.survey.templates (7 files)

**Option 1: Consolidate Down** ✅ Recommended

- Move templates code into ss.survey
- Result: Single component ss.survey
- Effort: Low (7 files to move)
- Rationale: Templates are small, related to survey functionality

**Option 2: Split Up**

- Create ss.survey.create (2 files)
- Create ss.survey.process (1 file)
- Create ss.survey.shared (3 files)
- Keep ss.survey.templates (7 files)
- Effort: High (multiple components to create)
- Rationale: More granular, but may be over-engineering

**Option 3: Move Shared Code**

- Create ss.survey.shared (3 shared files)
- Keep domain code in root (2 files)
- Keep ss.survey.templates (7 files)
- Effort: Medium
- Rationale: Separates shared from domain, but still has hierarchy
第 4 阶段:制定扁平化计划

为每个根命名空间生成重构计划:

  1. 选择策略

    • 选择最佳扁平化选项
    • 考虑工作量、复杂度和可维护性
  2. 规划重构步骤

    • 列出要移动的文件
    • 确定目标命名空间
    • 记录需要更新的依赖项
  3. 估算工作量

    • 重构所需时间
    • 风险评估
    • 测试要求

扁平化计划示例:

## Flattening Plan

### Priority: High

**Root Namespace: ss.survey**

**Strategy**: Consolidate Down

**Steps**:

1. Move files from ss.survey.templates/ to ss.survey/
   - EmailTemplate.js
   - SMSTemplate.js
   - [5 more files]

2. Update imports in dependent components
   - Update references from ss.survey.templates._ to ss.survey._

3. Remove ss.survey.templates/ directory

4. Update namespace declarations
   - Change namespace from ss.survey.templates to ss.survey

5. Run tests to verify changes

**Effort**: 2-3 days
**Risk**: Low (templates are self-contained)
**Dependencies**: None
第 5 阶段:执行扁平化

执行重构:

  1. 移动文件

    • 将源文件移动到目标命名空间
    • 更新文件路径和导入
  2. 更新引用

    • 更新依赖组件中的导入
    • 更新命名空间声明
    • 更新目录结构
  3. 验证更改

    • 运行测试
    • 检查是否存在失效引用
    • 验证组件结构

输出格式

孤立类报告
## Orphaned Classes Analysis

### Root Namespace: ss.survey

**Status**: ⚠️ Has Orphaned Classes

**Orphaned Files** (5 files):

- Survey.js (domain code)
- SurveyProcessor.js (domain code)
- SurveyValidator.js (shared code)
- SurveyFormatter.js (shared code)
- SurveyConstants.js (shared code)

**Leaf Components**:

- ss.survey.templates (7 files)

**Issue**: Root namespace contains code but is extended by leaf component

**Recommendation**: Consolidate templates into root namespace
组件层级问题
## Component Hierarchy Issues

| Root Namespace | Orphaned Files | Leaf Components                 | Issue                | Recommendation   |
| -------------- | -------------- | ------------------------------- | -------------------- | ---------------- |
| ss.survey      | 5              | 1 (templates)                   | Has orphaned classes | Consolidate down |
| ss.ticket      | 45             | 2 (assign, route)               | Large orphaned code  | Split up         |
| ss.reporting   | 0              | 3 (tickets, experts, financial) | No issue             | ✅ OK            |
扁平化计划
## Flattening Plan

### Priority: High

**ss.survey** → Consolidate Down

- Move 7 files from templates to root
- Effort: 2-3 days
- Risk: Low

### Priority: Medium

**ss.ticket** → Split Up

- Create ss.ticket.maintenance (30 files)
- Create ss.ticket.completion (10 files)
- Create ss.ticket.shared (5 files)
- Effort: 1 week
- Risk: Medium

分析检查清单

结构映射:

  • 已映射所有命名空间层级
  • 已识别根命名空间
  • 已找到所有源文件
  • 已标记叶节点(组件)

孤立类检测:

  • 已扫描根命名空间中的源文件
  • 已识别孤立类
  • 已对孤立类分类(共享/领域/混合)
  • 已评估影响和依赖关系

扁平化分析:

  • 已分析整合选项
  • 已分析拆分选项
  • 已分析提取共享代码选项
  • 已为每个根命名空间选择最佳策略

计划制定:

  • 已选择扁平化策略
  • 已制定重构步骤
  • 已估算工作量和风险
  • 已确定工作优先级

执行:

  • 已将文件移至目标命名空间
  • 已更新导入和引用
  • 已更新命名空间声明
  • 已通过测试验证更改

实施说明

对于 Node.js/Express 应用程序

组件通常位于 services/ 目录中:

services/
├── survey/              ← Root namespace (extended)
│   ├── Survey.js       ← Orphaned class
│   └── templates/      ← Component (leaf node)
│       └── Template.js

扁平化:

  • 整合:将 templates/ 文件移至 survey/
  • 拆分:创建 survey/create/ 和 survey/process/
  • 共享:为工具创建 survey/shared/
对于 Java 应用程序

通过包结构识别组件:

com.company.survey       ← Root package (extended)
├── Survey.java         ← Orphaned class
└── templates/          ← Component (leaf package)
    └── Template.java

扁平化:

  • 整合:将 templates 类移至 survey 包
  • 拆分:创建 survey.create 和 survey.process 包
  • 共享:创建 survey.shared 包
检测策略

查找包含代码的根命名空间:

// Find root namespaces containing source files
function findRootNamespacesWithCode(namespaces, sourceFiles) {
  const rootNamespaces = namespaces.filter((ns) => {
    // Check if namespace has been extended
    const hasChildren = namespaces.some((n) => n.startsWith(ns + '.') || n.startsWith(ns + '/'))

    // Check if namespace contains source files
    const hasFiles = sourceFiles.some((f) => f.namespace === ns)

    return hasChildren && hasFiles
  })

  return rootNamespaces
}

查找孤立类:

// Find orphaned classes in root namespaces
function findOrphanedClasses(rootNamespaces, sourceFiles) {
  const orphaned = []

  rootNamespaces.forEach((rootNs) => {
    const files = sourceFiles.filter((f) => f.namespace === rootNs)
    orphaned.push({
      rootNamespace: rootNs,
      files: files,
      count: files.length,
    })
  })

  return orphaned
}

适应度函数

扁平化组件后,创建自动化检查:

根命名空间中不应有源代码
// Alert if source code exists in root namespace
function checkRootNamespaceCode(namespaces, sourceFiles) {
  const violations = []

  namespaces.forEach((ns) => {
    // Check if namespace has been extended
    const hasChildren = namespaces.some((n) => n.startsWith(ns + '.') || n.startsWith(ns + '/'))

    if (hasChildren) {
      // Check if namespace contains source files
      const files = sourceFiles.filter((f) => f.namespace === ns)

      if (files.length > 0) {
        violations.push({
          namespace: ns,
          files: files.map((f) => f.name),
          issue: 'Root namespace contains source files (orphaned classes)',
        })
      }
    }
  })

  return violations
}
组件只能作为叶节点
// Ensure components exist only as leaf nodes
function validateComponentStructure(namespaces, sourceFiles) {
  const violations = []

  // Find all leaf nodes (components)
  const leafNodes = namespaces.filter((ns) => {
    return !namespaces.some((n) => n.startsWith(ns + '.') || n.startsWith(ns + '/'))
  })

  // Check that all source files are in leaf nodes
  sourceFiles.forEach((file) => {
    if (!leafNodes.includes(file.namespace)) {
      violations.push({
        file: file.name,
        namespace: file.namespace,
        issue: 'Source file not in leaf node (component)',
      })
    }
  })

  return violations
}

最佳实践

应做事项 ✅
  • 确保组件只作为叶节点存在
  • 从根命名空间中移除孤立的类
  • 根据功能选择扁平化策略
  • 功能相关时进行合并
  • 功能不同则进行拆分
  • 将共享代码提取到 .shared 组件
  • 扁平化后更新所有引用
  • 通过测试验证更改
不应做事项 ❌
  • 不要将孤立的类留在根命名空间中
  • 不要在其他组件之上创建组件
  • 移动文件后不要跳过更新导入
  • 不要在未分析影响的情况下进行扁平化
  • 不要不一致地混用扁平化策略
  • 扁平化时不要忽略共享代码
  • 重构后不要跳过测试

常见模式

模式 1:简单合并

之前:

ss.survey/
├── Survey.js           ← Orphaned
└── templates/          ← Component
    └── Template.js

之后:

ss.survey/              ← Component (leaf node)
├── Survey.js
└── Template.js
模式 2:按功能拆分

之前:

ss.ticket/              ← Root namespace
├── Ticket.js           ← Orphaned (45 files)
├── assign/             ← Component
└── route/              ← Component

之后:

ss.ticket/              ← Subdomain
├── maintenance/        ← Component
│   └── Ticket.js
├── completion/        ← Component
│   └── TicketCompletion.js
├── assign/             ← Component
└── route/              ← Component
模式 3:提取共享代码

之前:

ss.survey/              ← Root namespace
├── Survey.js           ← Domain code
├── SurveyValidator.js  ← Shared code
└── templates/          ← Component

之后:

ss.survey/              ← Component
├── Survey.js
└── shared/             ← Component
    └── SurveyValidator.js

后续步骤

扁平化组件后:

  1. 应用“确定组件依赖关系”模式 - 分析耦合
  2. 创建组件域 - 将组件分组到各个域中
  3. 创建域服务 - 将域提取为服务

注意事项

  • 组件只能作为叶节点存在
  • 含有代码的根命名空间会造成问题
  • 扁平化可提升组件的清晰度
  • 根据功能选择扁平化策略
  • 共享代码应放在专用组件中
  • 移动文件后始终更新引用
  • 扁平化后进行全面测试

评论

支持 Markdown