component-flattening-analysis
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseComponent 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 planExample 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 effortExample 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
分步流程
- Scan Structure: Map component namespace hierarchies
- Identify Issues: Find orphaned classes and component nesting
- Analyze Options: Determine flattening strategy (consolidate vs split)
- Create Plan: Generate refactoring plan with steps
- Execute: Refactor components to remove hierarchy
- 扫描结构:绘制Component命名空间层级图
- 识别问题:查找孤立类和Component嵌套
- 分析方案:确定扁平化策略(合并 vs 拆分)
- 制定计划:生成包含步骤的重构计划
- 执行重构:重构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: extended to
ss.surveyss.survey.templates - Result: becomes a root namespace (subdomain)
ss.survey
根命名空间是被扩展的命名空间节点:
- 被扩展:在其下方添加了其他命名空间节点
- 示例:被扩展为
ss.surveyss.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.jsFlattening Strategies
扁平化策略
Strategy 1: Consolidate Down
- Move code from leaf nodes into root namespace
- Makes root namespace the component
- Example: Move →
ss.survey.templatesss.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.createss.survey.process
Strategy 3: Move Shared Code
- Move shared code to dedicated component
- Creates component
.shared - Example: shared code →
ss.surveyss.survey.shared
策略1:向下合并
- 将叶子节点中的代码移动到根命名空间
- 使根命名空间成为Component
- 示例:将→
ss.survey.templatesss.survey
策略2:向上拆分
- 将根命名空间中的代码移动到新的叶子节点
- 从根命名空间创建新的Component
- 示例:将拆分为
ss.survey+ss.survey.createss.survey.process
策略3:移动共享代码
- 将共享代码移动到专用Component
- 创建Component
.shared - 示例:将中的共享代码 →
ss.surveyss.survey.shared
Analysis Process
分析流程
Phase 1: Map Component Structure
阶段1:绘制Component结构
Scan directory/namespace structure to identify hierarchy:
-
Map Namespace Tree
- Build tree of all namespaces
- Identify parent-child relationships
- Mark leaf nodes (components)
-
Identify Root Namespaces
- Find namespaces that have been extended
- Mark as root namespaces (subdomains)
- Note which namespaces extend them
-
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扫描目录/命名空间结构以识别层级:
-
绘制命名空间树
- 构建所有命名空间的树状结构
- 识别父子关系
- 标记叶子节点(Component)
-
识别根命名空间
- 查找已被扩展的命名空间
- 标记为根命名空间(子域)
- 记录哪些命名空间扩展了它们
-
定位源文件
- 查找每个命名空间中的所有源文件
- 将文件映射到对应的命名空间位置
- 识别根命名空间中的文件
结构绘制示例:
markdown
undefinedComponent 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
undefinedPhase 2: Identify Orphaned Classes
阶段2:识别孤立类
Find source files in root namespaces:
-
Scan Root Namespaces
- Check each root namespace for source files
- Identify files that are orphaned
- Count orphaned files per root namespace
-
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
-
Assess Impact
- How many files are orphaned?
- What functionality do they contain?
- What components depend on them?
Example Orphaned Class Detection:
markdown
undefined查找根命名空间中的源文件:
-
扫描根命名空间
- 检查每个根命名空间中的源文件
- 识别孤立类
- 统计每个根命名空间中的孤立文件数量
-
分类孤立类
- 共享代码:通用工具、接口、抽象类
- 领域代码:应属于Component的业务逻辑
- 混合代码:共享代码与领域代码的组合
-
评估影响
- 有多少个孤立文件?
- 它们包含哪些功能?
- 哪些Component依赖于它们?
孤立类检测示例:
markdown
undefinedOrphaned 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依赖
undefinedPhase 3: Analyze Flattening Options
阶段3:分析扁平化方案
Determine best flattening strategy for each root namespace:
-
Option 1: Consolidate Down
- Move leaf node code into root namespace
- Makes root namespace the component
- Use when: Leaf nodes are small, related functionality
-
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
-
Option 3: Move Shared Code
- Extract shared code to component
.shared - Keep domain code in root or split
- Use when: Root namespace has shared utilities
- Extract shared code to
Example Flattening Analysis:
markdown
undefined为每个根命名空间确定最佳扁平化策略:
-
方案1:向下合并
- 将叶子节点代码移动到根命名空间
- 使根命名空间成为Component
- 适用场景:叶子节点规模小、功能相关
-
方案2:向上拆分
- 将根命名空间代码移动到新的叶子节点
- 从根命名空间创建多个Component
- 适用场景:根命名空间包含不同的功能区域
-
方案3:移动共享代码
- 将共享代码提取到Component
.shared - 根命名空间中的领域代码保留或拆分
- 适用场景:根命名空间包含共享工具
- 将共享代码提取到
扁平化分析示例:
markdown
undefinedFlattening 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个文件)
- 工作量:中等
- 理由:分离共享代码与领域代码,但仍存在层级结构
undefinedPhase 4: Create Flattening Plan
阶段4:制定扁平化计划
Generate refactoring plan for each root namespace:
-
Select Strategy
- Choose best flattening option
- Consider effort, complexity, maintainability
-
Plan Refactoring Steps
- List files to move
- Identify target namespaces
- Note dependencies to update
-
Estimate Effort
- Time to refactor
- Risk assessment
- Testing requirements
Example Flattening Plan:
markdown
undefined为每个根命名空间生成重构计划:
-
选择策略
- 选择最佳扁平化方案
- 考虑工作量、复杂度、可维护性
-
规划重构步骤
- 列出需要移动的文件
- 确定目标命名空间
- 记录需要更新的依赖关系
-
评估工作量
- 重构所需时间
- 风险评估
- 测试要求
扁平化计划示例:
markdown
undefinedFlattening Plan
扁平化计划
Priority: High
优先级:高
Root Namespace: ss.survey
Strategy: Consolidate Down
Steps:
-
Move files from ss.survey.templates/ to ss.survey/
- EmailTemplate.js
- SMSTemplate.js
- [5 more files]
-
Update imports in dependent components
- Update references from ss.survey.templates._ to ss.survey._
-
Remove ss.survey.templates/ directory
-
Update namespace declarations
- Change namespace from ss.survey.templates to ss.survey
-
Run tests to verify changes
Effort: 2-3 days
Risk: Low (templates are self-contained)
Dependencies: None
undefined根命名空间:ss.survey
策略:向下合并
步骤:
-
将ss.survey.templates/中的文件移动到ss.survey/
- EmailTemplate.js
- SMSTemplate.js
- [另外5个文件]
-
更新依赖Component中的导入语句
- 将引用从ss.survey.templates.更新为ss.survey.
-
删除ss.survey.templates/目录
-
更新命名空间声明
- 将命名空间从ss.survey.templates改为ss.survey
-
运行测试以验证变更
工作量:2-3天
风险:低(Templates为独立模块)
依赖关系:无
undefinedPhase 5: Execute Flattening
阶段5:执行扁平化
Perform the refactoring:
-
Move Files
- Move source files to target namespace
- Update file paths and imports
-
Update References
- Update imports in dependent components
- Update namespace declarations
- Update directory structure
-
Verify Changes
- Run tests
- Check for broken references
- Validate component structure
执行重构操作:
-
移动文件
- 将源文件移动到目标命名空间
- 更新文件路径和导入语句
-
更新引用
- 更新依赖Component中的导入语句
- 更新命名空间声明
- 更新目录结构
-
验证变更
- 运行测试
- 检查是否存在无效引用
- 验证Component结构
Output Format
输出格式
Orphaned Classes Report
孤立类报告
markdown
undefinedmarkdown
undefinedOrphaned 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合并到根命名空间
undefinedComponent Hierarchy Issues
Component层级问题
markdown
undefinedmarkdown
undefinedComponent Hierarchy Issues
Component层级问题
| 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 |
undefined| 根命名空间 | 孤立文件数量 | 叶子Component | 问题 | 建议 |
|---|---|---|---|---|
| ss.survey | 5 | 1 (templates) | 存在孤立类 | 向下合并 |
| ss.ticket | 45 | 2 (assign, route) | 大量孤立代码 | 向上拆分 |
| ss.reporting | 0 | 3 (tickets, experts, financial) | 无问题 | ✅ 正常 |
undefinedFlattening Plan
扁平化计划
markdown
undefinedmarkdown
undefinedFlattening 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
undefinedss.ticket → 向上拆分
- 创建ss.ticket.maintenance(30个文件)
- 创建ss.ticket.completion(10个文件)
- 创建ss.ticket.shared(5个文件)
- 工作量:1周
- 风险:中等
undefinedAnalysis 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 directory:
services/services/
├── survey/ ← Root namespace (extended)
│ ├── Survey.js ← Orphaned class
│ └── templates/ ← Component (leaf node)
│ └── Template.jsFlattening:
- Consolidate: Move files to
templates/survey/ - Split: Create and
survey/create/survey/process/ - Shared: Create for utilities
survey/shared/
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.javaFlattening:
- Consolidate: Move classes to
templatespackagesurvey - Split: Create and
survey.createpackagessurvey.process - Shared: Create package
survey.shared
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 components
.shared - Update all references after flattening
- Verify changes with tests
- 确保Component仅作为叶子节点存在
- 移除根命名空间中的孤立类
- 根据功能选择扁平化策略
- 功能相关时进行合并
- 功能不同时进行拆分
- 将共享代码提取到Component
.shared - 扁平化后更新所有引用
- 通过测试验证变更
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.jsAfter:
ss.survey/ ← Component (leaf node)
├── Survey.js
└── Template.js重构前:
ss.survey/
├── Survey.js ← 孤立类
└── templates/ ← Component
└── Template.js重构后:
ss.survey/ ← Component(叶子节点)
├── Survey.js
└── Template.jsPattern 2: Functional Split
模式2:功能拆分
Before:
ss.ticket/ ← Root namespace
├── Ticket.js ← Orphaned (45 files)
├── assign/ ← Component
└── route/ ← ComponentAfter:
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/ ← ComponentPattern 3: Shared Code Extraction
模式3:共享代码提取
Before:
ss.survey/ ← Root namespace
├── Survey.js ← Domain code
├── SurveyValidator.js ← Shared code
└── templates/ ← ComponentAfter:
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.jsNext Steps
后续步骤
After flattening components:
- Apply Determine Component Dependencies Pattern - Analyze coupling
- Create Component Domains - Group components into domains
- Create Domain Services - Extract domains to services
扁平化Component后:
- 应用确定Component依赖关系模式 - 分析耦合性
- 创建Component领域 - 将Component分组到领域
- 创建领域服务 - 将领域提取为服务
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中
- 移动文件后务必更新引用
- 扁平化后需彻底测试