component-flattening-analysis

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Component Flattening Analysis

Component扁平化分析

This skill identifies component hierarchy issues and ensures components exist only as leaf nodes in directory/namespace structures, removing orphaned classes from root namespaces.
本技能可识别Component层级问题,确保Component仅作为目录/命名空间结构中的叶子节点存在,并移除根命名空间中的孤立类。

How to Use

使用方法

Quick Start

快速开始

Request analysis of your codebase:
  • "Find orphaned classes in root namespaces"
  • "Flatten component hierarchies"
  • "Identify components that need flattening"
  • "Analyze component structure for hierarchy issues"
请求分析你的代码库:
  • "查找根命名空间中的孤立类"
  • "扁平化Component层级"
  • "识别需要扁平化的Component"
  • "分析Component结构中的层级问题"

Usage Examples

使用示例

Example 1: Find Orphaned Classes
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
Example 2: Flatten Components
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
Example 3: Component Structure Analysis
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:查找孤立类
User: "Find orphaned classes in root namespaces"

该技能将:
1. 扫描Component命名空间以查找层级问题
2. 识别根命名空间中的孤立类
3. 检测基于其他Component构建的Component
4. 提出扁平化策略建议
5. 创建重构计划
示例2:扁平化Component
User: "Flatten component hierarchies in this codebase"

该技能将:
1. 识别存在层级问题的Component
2. 分析孤立类
3. 提出合并或拆分策略建议
4. 创建重构计划
5. 评估工作量
示例3:Component结构分析
User: "Analyze component structure for hierarchy issues"

该技能将:
1. 绘制Component命名空间结构
2. 识别包含代码的根命名空间
3. 查找基于其他Component构建的Component
4. 标记层级违规问题
5. 提供优化建议

Step-by-Step Process

分步流程

  1. Scan Structure: Map component namespace hierarchies
  2. Identify Issues: Find orphaned classes and component nesting
  3. Analyze Options: Determine flattening strategy (consolidate vs split)
  4. Create Plan: Generate refactoring plan with steps
  5. Execute: Refactor components to remove hierarchy
  1. 扫描结构:绘制Component命名空间层级图
  2. 识别问题:查找孤立类和Component嵌套
  3. 分析方案:确定扁平化策略(合并 vs 拆分)
  4. 制定计划:生成包含步骤的重构计划
  5. 执行重构:重构Component以移除层级结构

When to Use

适用场景

Apply this skill when:
  • After gathering common domain components (Pattern 2)
  • Before determining component dependencies (Pattern 4)
  • When components have nested structures
  • Finding orphaned classes in root namespaces
  • Preparing for domain grouping
  • Cleaning up component structure
  • Ensuring components are leaf nodes only
在以下场景应用本技能:
  • 收集通用领域Component之后(模式2)
  • 确定Component依赖关系之前(模式4)
  • 当Component存在嵌套结构时
  • 查找根命名空间中的孤立类时
  • 准备领域分组时
  • 清理Component结构时
  • 确保Component仅作为叶子节点存在时

Core Concepts

核心概念

Component Definition

Component定义

A component is identified by a leaf node in directory/namespace structure:
  • Leaf Node: The deepest directory containing source files
  • Component: Source code files in leaf node namespace
  • Subdomain: Parent namespace that has been extended
Key Rule: Components exist only as leaf nodes. If a namespace is extended, the parent becomes a subdomain, not a component.
Component由目录/命名空间结构中的叶子节点标识:
  • 叶子节点:包含源文件的最深层级目录
  • Component:叶子节点命名空间中的源文件
  • 子域:被扩展的父命名空间
关键规则:Component仅能作为叶子节点存在。如果某个命名空间被扩展,其父级将成为子域,而非Component。

Root Namespace

根命名空间

A root namespace is a namespace node that has been extended:
  • Extended: Another namespace node added below it
  • Example:
    ss.survey
    extended to
    ss.survey.templates
  • Result:
    ss.survey
    becomes a root namespace (subdomain)
根命名空间是被扩展的命名空间节点:
  • 被扩展:在其下方添加了其他命名空间节点
  • 示例
    ss.survey
    被扩展为
    ss.survey.templates
  • 结果
    ss.survey
    成为根命名空间(子域)

Orphaned Classes

孤立类

Orphaned classes are source files in root namespaces:
  • Location: Root namespace (non-leaf node)
  • Problem: No definable component associated with them
  • Solution: Move to leaf node namespace (component)
Example:
ss.survey/              ← Root namespace (extended by .templates)
├── Survey.js           ← Orphaned class (in root namespace)
└── templates/          ← Component (leaf node)
    └── Template.js
孤立类是根命名空间中的源文件:
  • 位置:根命名空间(非叶子节点)
  • 问题:无法与可定义的Component关联
  • 解决方案:移动到叶子节点命名空间(Component)
示例
ss.survey/              ← 根命名空间(已被扩展)
├── Survey.js           ← 孤立类(位于根命名空间)
└── templates/          ← Component(叶子节点)
    └── Template.js

Flattening Strategies

扁平化策略

Strategy 1: Consolidate Down
  • Move code from leaf nodes into root namespace
  • Makes root namespace the component
  • Example: Move
    ss.survey.templates
    ss.survey
Strategy 2: Split Up
  • Move code from root namespace into new leaf nodes
  • Creates new components from root namespace
  • Example: Split
    ss.survey
    ss.survey.create
    +
    ss.survey.process
Strategy 3: Move Shared Code
  • Move shared code to dedicated component
  • Creates
    .shared
    component
  • Example:
    ss.survey
    shared code →
    ss.survey.shared
策略1:向下合并
  • 将叶子节点中的代码移动到根命名空间
  • 使根命名空间成为Component
  • 示例:将
    ss.survey.templates
    ss.survey
策略2:向上拆分
  • 将根命名空间中的代码移动到新的叶子节点
  • 从根命名空间创建新的Component
  • 示例:将
    ss.survey
    拆分为
    ss.survey.create
    +
    ss.survey.process
策略3:移动共享代码
  • 将共享代码移动到专用Component
  • 创建
    .shared
    Component
  • 示例:将
    ss.survey
    中的共享代码 →
    ss.survey.shared

Analysis Process

分析流程

Phase 1: Map Component Structure

阶段1:绘制Component结构

Scan directory/namespace structure to identify hierarchy:
  1. Map Namespace Tree
    • Build tree of all namespaces
    • Identify parent-child relationships
    • Mark leaf nodes (components)
  2. Identify Root Namespaces
    • Find namespaces that have been extended
    • Mark as root namespaces (subdomains)
    • Note which namespaces extend them
  3. Locate Source Files
    • Find all source files in each namespace
    • Map files to their namespace location
    • Identify files in root namespaces
Example Structure Mapping:
markdown
undefined
扫描目录/命名空间结构以识别层级:
  1. 绘制命名空间树
    • 构建所有命名空间的树状结构
    • 识别父子关系
    • 标记叶子节点(Component)
  2. 识别根命名空间
    • 查找已被扩展的命名空间
    • 标记为根命名空间(子域)
    • 记录哪些命名空间扩展了它们
  3. 定位源文件
    • 查找每个命名空间中的所有源文件
    • 将文件映射到对应的命名空间位置
    • 识别根命名空间中的文件
结构绘制示例
markdown
undefined

Component Structure Map

Component结构映射


ss.survey/ ← Root namespace (extended)
├── Survey.js ← Orphaned class
├── SurveyProcessor.js ← Orphaned class
└── templates/ ← Component (leaf node)
├── EmailTemplate.js
└── SMSTemplate.js

ss.ticket/ ← Root namespace (extended)
├── Ticket.js ← Orphaned class
├── assign/ ← Component (leaf node)
│ └── TicketAssign.js
└── route/ ← Component (leaf node)
└── TicketRoute.js
undefined

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

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

Phase 2: Identify Orphaned Classes

阶段2:识别孤立类

Find source files in root namespaces:
  1. Scan Root Namespaces
    • Check each root namespace for source files
    • Identify files that are orphaned
    • Count orphaned files per root namespace
  2. Classify Orphaned Classes
    • Shared Code: Common utilities, interfaces, abstract classes
    • Domain Code: Business logic that should be in component
    • Mixed: Combination of shared and domain code
  3. Assess Impact
    • How many files are orphaned?
    • What functionality do they contain?
    • What components depend on them?
Example Orphaned Class Detection:
markdown
undefined
查找根命名空间中的源文件:
  1. 扫描根命名空间
    • 检查每个根命名空间中的源文件
    • 识别孤立类
    • 统计每个根命名空间中的孤立文件数量
  2. 分类孤立类
    • 共享代码:通用工具、接口、抽象类
    • 领域代码:应属于Component的业务逻辑
    • 混合代码:共享代码与领域代码的组合
  3. 评估影响
    • 有多少个孤立文件?
    • 它们包含哪些功能?
    • 哪些Component依赖于它们?
孤立类检测示例
markdown
undefined

Orphaned Classes Found

已发现的孤立类

Root Namespace: ss.survey

根命名空间: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
undefined
孤立文件(5个):
  • Survey.js(领域代码 - 问卷创建)
  • SurveyProcessor.js(领域代码 - 问卷处理)
  • SurveyValidator.js(共享代码 - 验证)
  • SurveyFormatter.js(共享代码 - 格式化)
  • SurveyConstants.js(共享代码 - 常量)
分类
  • 领域代码:2个文件(应属于Component)
  • 共享代码:3个文件(应属于.shared Component)
依赖关系:被ss.survey.templates Component依赖
undefined

Phase 3: Analyze Flattening Options

阶段3:分析扁平化方案

Determine best flattening strategy for each root namespace:
  1. Option 1: Consolidate Down
    • Move leaf node code into root namespace
    • Makes root namespace the component
    • Use when: Leaf nodes are small, related functionality
  2. Option 2: Split Up
    • Move root namespace code into new leaf nodes
    • Creates multiple components from root
    • Use when: Root namespace has distinct functional areas
  3. Option 3: Move Shared Code
    • Extract shared code to
      .shared
      component
    • Keep domain code in root or split
    • Use when: Root namespace has shared utilities
Example Flattening Analysis:
markdown
undefined
为每个根命名空间确定最佳扁平化策略:
  1. 方案1:向下合并
    • 将叶子节点代码移动到根命名空间
    • 使根命名空间成为Component
    • 适用场景:叶子节点规模小、功能相关
  2. 方案2:向上拆分
    • 将根命名空间代码移动到新的叶子节点
    • 从根命名空间创建多个Component
    • 适用场景:根命名空间包含不同的功能区域
  3. 方案3:移动共享代码
    • 将共享代码提取到
      .shared
      Component
    • 根命名空间中的领域代码保留或拆分
    • 适用场景:根命名空间包含共享工具
扁平化分析示例
markdown
undefined

Flattening Options Analysis

扁平化方案分析

Root Namespace: ss.survey

根命名空间: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
undefined
当前状态
  • 根命名空间:5个孤立文件
  • 叶子Component:ss.survey.templates(7个文件)
方案1:向下合并 ✅ 推荐
  • 将templates代码移动到ss.survey
  • 结果:单个Component ss.survey
  • 工作量:低(需移动7个文件)
  • 理由:Templates规模小,与问卷功能相关
方案2:向上拆分
  • 创建ss.survey.create(2个文件)
  • 创建ss.survey.process(1个文件)
  • 创建ss.survey.shared(3个文件)
  • 保留ss.survey.templates(7个文件)
  • 工作量:高(需创建多个Component)
  • 理由:粒度更细,但可能过度设计
方案3:移动共享代码
  • 创建ss.survey.shared(3个共享文件)
  • 根命名空间保留领域代码(2个文件)
  • 保留ss.survey.templates(7个文件)
  • 工作量:中等
  • 理由:分离共享代码与领域代码,但仍存在层级结构
undefined

Phase 4: Create Flattening Plan

阶段4:制定扁平化计划

Generate refactoring plan for each root namespace:
  1. Select Strategy
    • Choose best flattening option
    • Consider effort, complexity, maintainability
  2. Plan Refactoring Steps
    • List files to move
    • Identify target namespaces
    • Note dependencies to update
  3. Estimate Effort
    • Time to refactor
    • Risk assessment
    • Testing requirements
Example Flattening Plan:
markdown
undefined
为每个根命名空间生成重构计划:
  1. 选择策略
    • 选择最佳扁平化方案
    • 考虑工作量、复杂度、可维护性
  2. 规划重构步骤
    • 列出需要移动的文件
    • 确定目标命名空间
    • 记录需要更新的依赖关系
  3. 评估工作量
    • 重构所需时间
    • 风险评估
    • 测试要求
扁平化计划示例
markdown
undefined

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
undefined
根命名空间:ss.survey
策略:向下合并
步骤
  1. 将ss.survey.templates/中的文件移动到ss.survey/
    • EmailTemplate.js
    • SMSTemplate.js
    • [另外5个文件]
  2. 更新依赖Component中的导入语句
    • 将引用从ss.survey.templates.更新为ss.survey.
  3. 删除ss.survey.templates/目录
  4. 更新命名空间声明
    • 将命名空间从ss.survey.templates改为ss.survey
  5. 运行测试以验证变更
工作量:2-3天 风险:低(Templates为独立模块) 依赖关系:无
undefined

Phase 5: Execute Flattening

阶段5:执行扁平化

Perform the refactoring:
  1. Move Files
    • Move source files to target namespace
    • Update file paths and imports
  2. Update References
    • Update imports in dependent components
    • Update namespace declarations
    • Update directory structure
  3. Verify Changes
    • Run tests
    • Check for broken references
    • Validate component structure
执行重构操作:
  1. 移动文件
    • 将源文件移动到目标命名空间
    • 更新文件路径和导入语句
  2. 更新引用
    • 更新依赖Component中的导入语句
    • 更新命名空间声明
    • 更新目录结构
  3. 验证变更
    • 运行测试
    • 检查是否存在无效引用
    • 验证Component结构

Output Format

输出格式

Orphaned Classes Report

孤立类报告

markdown
undefined
markdown
undefined

Orphaned Classes Analysis

孤立类分析

Root Namespace: ss.survey

根命名空间: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
undefined
状态:⚠️ 存在孤立类
孤立文件(5个):
  • Survey.js(领域代码)
  • SurveyProcessor.js(领域代码)
  • SurveyValidator.js(共享代码)
  • SurveyFormatter.js(共享代码)
  • SurveyConstants.js(共享代码)
叶子Component
  • ss.survey.templates(7个文件)
问题:根命名空间包含代码,但已被叶子Component扩展
建议:将templates合并到根命名空间
undefined

Component Hierarchy Issues

Component层级问题

markdown
undefined
markdown
undefined

Component Hierarchy Issues

Component层级问题

Root NamespaceOrphaned FilesLeaf ComponentsIssueRecommendation
ss.survey51 (templates)Has orphaned classesConsolidate down
ss.ticket452 (assign, route)Large orphaned codeSplit up
ss.reporting03 (tickets, experts, financial)No issue✅ OK
undefined
根命名空间孤立文件数量叶子Component问题建议
ss.survey51 (templates)存在孤立类向下合并
ss.ticket452 (assign, route)大量孤立代码向上拆分
ss.reporting03 (tickets, experts, financial)无问题✅ 正常
undefined

Flattening Plan

扁平化计划

markdown
undefined
markdown
undefined

Flattening Plan

扁平化计划

Priority: High

优先级:高

ss.survey → Consolidate Down
  • Move 7 files from templates to root
  • Effort: 2-3 days
  • Risk: Low
ss.survey → 向下合并
  • 将7个文件从templates移动到根命名空间
  • 工作量:2-3天
  • 风险:低

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
undefined
ss.ticket → 向上拆分
  • 创建ss.ticket.maintenance(30个文件)
  • 创建ss.ticket.completion(10个文件)
  • 创建ss.ticket.shared(5个文件)
  • 工作量:1周
  • 风险:中等
undefined

Analysis Checklist

分析检查清单

Structure Mapping:
  • Mapped all namespace hierarchies
  • Identified root namespaces
  • Located all source files
  • Marked leaf nodes (components)
Orphaned Class Detection:
  • Scanned root namespaces for source files
  • Identified orphaned classes
  • Classified orphaned classes (shared/domain/mixed)
  • Assessed impact and dependencies
Flattening Analysis:
  • Analyzed consolidation option
  • Analyzed splitting option
  • Analyzed shared code extraction option
  • Selected best strategy for each root namespace
Plan Creation:
  • Selected flattening strategy
  • Created refactoring steps
  • Estimated effort and risk
  • Prioritized work
Execution:
  • Moved files to target namespaces
  • Updated imports and references
  • Updated namespace declarations
  • Verified changes with tests
结构绘制
  • 绘制所有命名空间层级
  • 识别根命名空间
  • 定位所有源文件
  • 标记叶子节点(Component)
孤立类检测
  • 扫描根命名空间中的源文件
  • 识别孤立类
  • 分类孤立类(共享/领域/混合)
  • 评估影响和依赖关系
扁平化分析
  • 分析合并方案
  • 分析拆分方案
  • 分析共享代码提取方案
  • 为每个根命名空间选择最佳策略
计划制定
  • 选择扁平化策略
  • 创建重构步骤
  • 评估工作量和风险
  • 确定工作优先级
执行
  • 将文件移动到目标命名空间
  • 更新导入语句和引用
  • 更新命名空间声明
  • 通过测试验证变更

Implementation Notes

实现说明

For Node.js/Express Applications

适用于Node.js/Express应用

Components typically in
services/
directory:
services/
├── survey/              ← Root namespace (extended)
│   ├── Survey.js       ← Orphaned class
│   └── templates/      ← Component (leaf node)
│       └── Template.js
Flattening:
  • Consolidate: Move
    templates/
    files to
    survey/
  • Split: Create
    survey/create/
    and
    survey/process/
  • Shared: Create
    survey/shared/
    for utilities
Component通常位于
services/
目录:
services/
├── survey/              ← 根命名空间(已被扩展)
│   ├── Survey.js       ← 孤立类
│   └── templates/      ← Component(叶子节点)
│       └── Template.js
扁平化方式
  • 合并:将
    templates/
    文件移动到
    survey/
  • 拆分:创建
    survey/create/
    survey/process/
  • 共享代码:创建
    survey/shared/
    存储工具类

For Java Applications

适用于Java应用

Components identified by package structure:
com.company.survey       ← Root package (extended)
├── Survey.java         ← Orphaned class
└── templates/          ← Component (leaf package)
    └── Template.java
Flattening:
  • Consolidate: Move
    templates
    classes to
    survey
    package
  • Split: Create
    survey.create
    and
    survey.process
    packages
  • Shared: Create
    survey.shared
    package
Component通过包结构识别:
com.company.survey       ← 根包(已被扩展)
├── Survey.java         ← 孤立类
└── templates/          ← Component(叶子包)
    └── Template.java
扁平化方式
  • 合并:将
    templates
    类移动到
    survey
  • 拆分:创建
    survey.create
    survey.process
  • 共享代码:创建
    survey.shared

Detection Strategies

检测策略

Find Root Namespaces with Code:
javascript
// 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:
javascript
// 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
}
查找包含代码的根命名空间
javascript
// 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
}
查找孤立类
javascript
// 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
}

Fitness Functions

适配函数

After flattening components, create automated checks:
扁平化Component后,创建自动化检查:

No Source Code in Root Namespaces

根命名空间中无源代码

javascript
// 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
}
javascript
// 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
}

Components Only as Leaf Nodes

Component仅作为叶子节点存在

javascript
// 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
}
javascript
// 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
}

Best Practices

最佳实践

Do's ✅

推荐做法 ✅

  • Ensure components exist only as leaf nodes
  • Remove orphaned classes from root namespaces
  • Choose flattening strategy based on functionality
  • Consolidate when functionality is related
  • Split when functionality is distinct
  • Extract shared code to
    .shared
    components
  • Update all references after flattening
  • Verify changes with tests
  • 确保Component仅作为叶子节点存在
  • 移除根命名空间中的孤立类
  • 根据功能选择扁平化策略
  • 功能相关时进行合并
  • 功能不同时进行拆分
  • 将共享代码提取到
    .shared
    Component
  • 扁平化后更新所有引用
  • 通过测试验证变更

Don'ts ❌

不推荐做法 ❌

  • Don't leave orphaned classes in root namespaces
  • Don't create components on top of other components
  • Don't skip updating imports after moving files
  • Don't flatten without analyzing impact
  • Don't mix flattening strategies inconsistently
  • Don't ignore shared code when flattening
  • Don't skip testing after refactoring
  • 不要在根命名空间中保留孤立类
  • 不要在其他Component之上创建Component
  • 移动文件后不要跳过更新导入语句
  • 不要在未分析影响的情况下进行扁平化
  • 不要不一致地混合使用扁平化策略
  • 扁平化时不要忽略共享代码
  • 重构后不要跳过测试

Common Patterns

常见模式

Pattern 1: Simple Consolidation

模式1:简单合并

Before:
ss.survey/
├── Survey.js           ← Orphaned
└── templates/          ← Component
    └── Template.js
After:
ss.survey/              ← Component (leaf node)
├── Survey.js
└── Template.js
重构前
ss.survey/
├── Survey.js           ← 孤立类
└── templates/          ← Component
    └── Template.js
重构后
ss.survey/              ← Component(叶子节点)
├── Survey.js
└── Template.js

Pattern 2: Functional Split

模式2:功能拆分

Before:
ss.ticket/              ← Root namespace
├── Ticket.js           ← Orphaned (45 files)
├── assign/             ← Component
└── route/              ← Component
After:
ss.ticket/              ← Subdomain
├── maintenance/        ← Component
│   └── Ticket.js
├── completion/        ← Component
│   └── TicketCompletion.js
├── assign/             ← Component
└── route/              ← Component
重构前
ss.ticket/              ← 根命名空间
├── Ticket.js           ← 孤立类(45个文件)
├── assign/             ← Component
└── route/              ← Component
重构后
ss.ticket/              ← 子域
├── maintenance/        ← Component
│   └── Ticket.js
├── completion/        ← Component
│   └── TicketCompletion.js
├── assign/             ← Component
└── route/              ← Component

Pattern 3: Shared Code Extraction

模式3:共享代码提取

Before:
ss.survey/              ← Root namespace
├── Survey.js           ← Domain code
├── SurveyValidator.js  ← Shared code
└── templates/          ← Component
After:
ss.survey/              ← Component
├── Survey.js
└── shared/             ← Component
    └── SurveyValidator.js
重构前
ss.survey/              ← 根命名空间
├── Survey.js           ← 领域代码
├── SurveyValidator.js  ← 共享代码
└── templates/          ← Component
重构后
ss.survey/              ← Component
├── Survey.js
└── shared/             ← Component
    └── SurveyValidator.js

Next Steps

后续步骤

After flattening components:
  1. Apply Determine Component Dependencies Pattern - Analyze coupling
  2. Create Component Domains - Group components into domains
  3. Create Domain Services - Extract domains to services
扁平化Component后:
  1. 应用确定Component依赖关系模式 - 分析耦合性
  2. 创建Component领域 - 将Component分组到领域
  3. 创建领域服务 - 将领域提取为服务

Notes

注意事项

  • Components must exist only as leaf nodes
  • Root namespaces with code are problematic
  • Flattening improves component clarity
  • Choose flattening strategy based on functionality
  • Shared code should be in dedicated components
  • Always update references after moving files
  • Test thoroughly after flattening
  • Component必须仅作为叶子节点存在
  • 包含代码的根命名空间存在问题
  • 扁平化可提升Component清晰度
  • 根据功能选择扁平化策略
  • 共享代码应位于专用Component中
  • 移动文件后务必更新引用
  • 扁平化后需彻底测试