pdd-skills 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1478 -0
- package/bin/pdd.js +354 -0
- package/config/bpmn-rules.yaml +166 -0
- package/config/checkstyle.xml +105 -0
- package/config/eslint.config.js +48 -0
- package/config/pmd.xml +91 -0
- package/config/prd-rules.yaml +113 -0
- package/config/ruff.toml +45 -0
- package/config/sqlfluff.cfg +82 -0
- package/hooks/hook-executor.js +332 -0
- package/index.js +43 -0
- package/lib/api-routes.js +750 -0
- package/lib/api-server.js +408 -0
- package/lib/cache/cache-config.js +209 -0
- package/lib/cache/system-cache.js +852 -0
- package/lib/config-manager.js +373 -0
- package/lib/generate.js +528 -0
- package/lib/grpc/grpc-routes.js +1134 -0
- package/lib/grpc/grpc-server.js +912 -0
- package/lib/grpc/proto-definitions.js +1033 -0
- package/lib/init.js +172 -0
- package/lib/iteration/auto-fixer.js +1025 -0
- package/lib/iteration/auto-reviewer.js +923 -0
- package/lib/iteration/controller.js +577 -0
- package/lib/list.js +130 -0
- package/lib/mcp-server.js +548 -0
- package/lib/openclaw/api-integration.js +535 -0
- package/lib/openclaw/cli-integration.js +567 -0
- package/lib/openclaw/data-sync.js +845 -0
- package/lib/openclaw/openclaw-adapter.js +783 -0
- package/lib/plugin/example-plugins/code-stats/index.js +332 -0
- package/lib/plugin/example-plugins/code-stats/plugin.json +1 -0
- package/lib/plugin/example-plugins/custom-linter/index.js +472 -0
- package/lib/plugin/example-plugins/custom-linter/plugin.json +1 -0
- package/lib/plugin/example-plugins/hello-world/index.js +86 -0
- package/lib/plugin/example-plugins/hello-world/plugin.json +1 -0
- package/lib/plugin/plugin-manager.js +655 -0
- package/lib/plugin/plugin-sdk.js +565 -0
- package/lib/plugin/sandbox.js +627 -0
- package/lib/quality/rules/maintainability.js +418 -0
- package/lib/quality/rules/performance.js +498 -0
- package/lib/quality/rules/readability.js +441 -0
- package/lib/quality/rules/robustness.js +504 -0
- package/lib/quality/rules/security.js +444 -0
- package/lib/quality/scorer.js +576 -0
- package/lib/report.js +669 -0
- package/lib/sdk-base.js +301 -0
- package/lib/sdk-js.js +446 -0
- package/lib/sdk-python/README.md +546 -0
- package/lib/sdk-python/examples/basic_usage.py +450 -0
- package/lib/sdk-python/pdd_sdk/__init__.py +180 -0
- package/lib/sdk-python/pdd_sdk/client.py +1170 -0
- package/lib/sdk-python/pdd_sdk/events.py +423 -0
- package/lib/sdk-python/pdd_sdk/exceptions.py +158 -0
- package/lib/sdk-python/pdd_sdk/models.py +518 -0
- package/lib/sdk-python/pdd_sdk/utils.py +759 -0
- package/lib/token/budget-alert.js +367 -0
- package/lib/token/budget-manager.js +485 -0
- package/lib/update.js +54 -0
- package/lib/utils/logger.js +88 -0
- package/lib/verify.js +741 -0
- package/lib/version.js +52 -0
- package/lib/vm/README.md +102 -0
- package/lib/vm/dashboard/api-routes.js +669 -0
- package/lib/vm/dashboard/server.js +391 -0
- package/lib/vm/dashboard/sse.js +358 -0
- package/lib/vm/dashboard/static/css/dashboard.css +1378 -0
- package/lib/vm/dashboard/static/index.html +118 -0
- package/lib/vm/dashboard/static/js/app.js +949 -0
- package/lib/vm/dashboard/static/js/charts.js +913 -0
- package/lib/vm/dashboard/static/js/kanban-view.js +1053 -0
- package/lib/vm/dashboard/static/js/pipeline-view.js +463 -0
- package/lib/vm/dashboard/static/js/quality-view.js +598 -0
- package/lib/vm/dashboard/static/js/system-view.js +1021 -0
- package/lib/vm/data-provider.js +1191 -0
- package/lib/vm/event-bus.js +402 -0
- package/lib/vm/hooks/extract-hook.js +307 -0
- package/lib/vm/hooks/generate-hook.js +374 -0
- package/lib/vm/hooks/hook-interface.js +458 -0
- package/lib/vm/hooks/report-hook.js +331 -0
- package/lib/vm/hooks/verify-hook.js +454 -0
- package/lib/vm/models.js +1003 -0
- package/lib/vm/reconciler.js +855 -0
- package/lib/vm/scanner.js +988 -0
- package/lib/vm/state-schema.js +955 -0
- package/lib/vm/state-store.js +733 -0
- package/lib/vm/tui/components/card.js +339 -0
- package/lib/vm/tui/components/progress-bar.js +368 -0
- package/lib/vm/tui/components/sparkline.js +327 -0
- package/lib/vm/tui/components/status-light.js +294 -0
- package/lib/vm/tui/components/table.js +370 -0
- package/lib/vm/tui/input.js +335 -0
- package/lib/vm/tui/renderer.js +548 -0
- package/lib/vm/tui/screens/kanban-screen.js +397 -0
- package/lib/vm/tui/screens/overview-screen.js +357 -0
- package/lib/vm/tui/screens/quality-screen.js +336 -0
- package/lib/vm/tui/screens/system-screen.js +379 -0
- package/lib/vm/tui/tui.js +805 -0
- package/package.json +1 -0
- package/scripts/cso-analyzer.js +198 -0
- package/scripts/eval-runner.js +359 -0
- package/scripts/i18n-checker.js +109 -0
- package/scripts/linter/activiti-linter.js +272 -0
- package/scripts/linter/prd-linter.js +162 -0
- package/scripts/linter/report-generator.js +207 -0
- package/scripts/linter/run-linters.js +285 -0
- package/scripts/linter/sql-linter.js +166 -0
- package/scripts/token-analyzer.js +162 -0
- package/scripts/vm-test.js +180 -0
- package/skills/core/official-doc-writer/LICENSE +21 -0
- package/skills/core/official-doc-writer/README.md +232 -0
- package/skills/core/official-doc-writer/SKILL.md +475 -0
- package/skills/core/official-doc-writer/_meta.json +1 -0
- package/skills/core/official-doc-writer/document_generator.py +580 -0
- package/skills/core/official-doc-writer/evals/default-evals.json +1 -0
- package/skills/core/official-doc-writer/examples.md +150 -0
- package/skills/core/official-doc-writer/fonts/FONTS_LIST.md +45 -0
- package/skills/core/official-doc-writer/fonts/README.md +141 -0
- package/skills/core/official-doc-writer/fonts/SIMFANG.TTF +0 -0
- package/skills/core/official-doc-writer/fonts/SIMHEI.TTF +0 -0
- package/skills/core/official-doc-writer/fonts/SIMKAI.TTF +0 -0
- package/skills/core/official-doc-writer/fonts/SIMSUN.TTC +0 -0
- package/skills/core/official-doc-writer/fonts//346/226/271/346/255/243/345/260/217/346/240/207/345/256/213GBK.TTF +0 -0
- package/skills/core/official-doc-writer/references/GBT_9704-2012_/345/205/232/346/224/277/346/234/272/345/205/263/345/205/254/346/226/207/346/240/274/345/274/217.md +422 -0
- package/skills/core/official-doc-writer/scripts/__pycache__/generate_official_doc.cpython-313.pyc +0 -0
- package/skills/core/official-doc-writer/scripts/dialog_manager.py +564 -0
- package/skills/core/official-doc-writer/scripts/generate_official_doc.py +252 -0
- package/skills/core/official-doc-writer/scripts/install_fonts.py +390 -0
- package/skills/core/official-doc-writer/scripts/smart_prompts.py +363 -0
- package/skills/core/pdd-ba/SKILL.md +305 -0
- package/skills/core/pdd-ba/_meta.json +1 -0
- package/skills/core/pdd-ba/evals/default-evals.json +1 -0
- package/skills/core/pdd-code-reviewer/SKILL.md +378 -0
- package/skills/core/pdd-code-reviewer/_meta.json +1 -0
- package/skills/core/pdd-code-reviewer/evals/default-evals.json +1 -0
- package/skills/core/pdd-doc-change/SKILL.md +350 -0
- package/skills/core/pdd-doc-change/_meta.json +1 -0
- package/skills/core/pdd-doc-change/evals/default-evals.json +1 -0
- package/skills/core/pdd-doc-gardener/SKILL.md +248 -0
- package/skills/core/pdd-doc-gardener/_meta.json +1 -0
- package/skills/core/pdd-doc-gardener/evals/default-evals.json +1 -0
- package/skills/core/pdd-entropy-reduction/SKILL.md +360 -0
- package/skills/core/pdd-entropy-reduction/_meta.json +1 -0
- package/skills/core/pdd-entropy-reduction/evals/default-evals.json +1 -0
- package/skills/core/pdd-entropy-reduction/references/entropy-report-template.md +287 -0
- package/skills/core/pdd-entropy-reduction/references/golden-principles.md +573 -0
- package/skills/core/pdd-entropy-reduction/scripts/entropy_scan.py +712 -0
- package/skills/core/pdd-extract-features/SKILL.md +320 -0
- package/skills/core/pdd-extract-features/_meta.json +1 -0
- package/skills/core/pdd-extract-features/evals/default-evals.json +1 -0
- package/skills/core/pdd-generate-spec/SKILL.md +418 -0
- package/skills/core/pdd-generate-spec/_meta.json +1 -0
- package/skills/core/pdd-generate-spec/evals/default-evals.json +1 -0
- package/skills/core/pdd-implement-feature/SKILL.md +332 -0
- package/skills/core/pdd-implement-feature/_meta.json +1 -0
- package/skills/core/pdd-implement-feature/evals/default-evals.json +1 -0
- package/skills/core/pdd-main/SKILL.md +540 -0
- package/skills/core/pdd-main/_meta.json +1 -0
- package/skills/core/pdd-main/evals/default-evals.json +1 -0
- package/skills/core/pdd-main/evals/evals.json +215 -0
- package/skills/core/pdd-verify-feature/SKILL.md +474 -0
- package/skills/core/pdd-verify-feature/_meta.json +1 -0
- package/skills/core/pdd-verify-feature/evals/default-evals.json +1 -0
- package/skills/core/pdd-vm/evals/default-evals.json +1 -0
- package/skills/core/traffic-accident-assessor/LICENSE +29 -0
- package/skills/core/traffic-accident-assessor/SKILL.md +439 -0
- package/skills/core/traffic-accident-assessor/evals/evals.json +1 -0
- package/skills/core/traffic-accident-assessor/references/accident-types.md +369 -0
- package/skills/core/traffic-accident-assessor/references/liability-rules.md +287 -0
- package/skills/core/traffic-accident-assessor/references/traffic-laws.md +226 -0
- package/skills/core/traffic-accident-assessor/references//351/253/230/345/260/224/345/244/253/350/257/264/346/230/216/344/271/246.pdf +32576 -106
- package/skills/core/traffic-accident-assessor/scripts/generate_official_statement.py +588 -0
- package/skills/core/traffic-accident-assessor/scripts/generate_report.py +495 -0
- package/skills/core/traffic-accident-assessor/scripts/generate_statement.py +528 -0
- package/skills/core/traffic-accident-assessor.zip +0 -0
- package/skills/entropy/expert-arch-enforcer/SKILL.md +292 -0
- package/skills/entropy/expert-arch-enforcer/_meta.json +1 -0
- package/skills/entropy/expert-arch-enforcer/evals/default-evals.json +1 -0
- package/skills/entropy/expert-auto-refactor/SKILL.md +327 -0
- package/skills/entropy/expert-auto-refactor/_meta.json +1 -0
- package/skills/entropy/expert-auto-refactor/evals/default-evals.json +1 -0
- package/skills/entropy/expert-code-quality/SKILL.md +468 -0
- package/skills/entropy/expert-code-quality/_meta.json +1 -0
- package/skills/entropy/expert-code-quality/evals/default-evals.json +1 -0
- package/skills/entropy/expert-code-quality/evals/evals.json +109 -0
- package/skills/entropy/expert-code-quality/references/code-smells.md +605 -0
- package/skills/entropy/expert-code-quality/references/design-patterns.md +1111 -0
- package/skills/entropy/expert-code-quality/references/refactoring-catalog.md +1281 -0
- package/skills/entropy/expert-code-quality/references/solid-principles.md +524 -0
- package/skills/entropy/expert-entropy-auditor/SKILL.md +276 -0
- package/skills/entropy/expert-entropy-auditor/_meta.json +1 -0
- package/skills/entropy/expert-entropy-auditor/evals/default-evals.json +1 -0
- package/skills/expert/expert-activiti/SKILL.md +497 -0
- package/skills/expert/expert-activiti/_meta.json +1 -0
- package/skills/expert/expert-mysql/SKILL.md +832 -0
- package/skills/expert/expert-mysql/_meta.json +1 -0
- package/skills/expert/expert-performance/SKILL.md +379 -0
- package/skills/expert/expert-performance/_meta.json +1 -0
- package/skills/expert/expert-performance/evals/default-evals.json +1 -0
- package/skills/expert/expert-ruoyi/SKILL.md +472 -0
- package/skills/expert/expert-ruoyi/_meta.json +1 -0
- package/skills/expert/expert-security/SKILL.md +1341 -0
- package/skills/expert/expert-security/_meta.json +1 -0
- package/skills/expert/expert-security/evals/default-evals.json +1 -0
- package/skills/expert/software-architect/SKILL.md +350 -0
- package/skills/expert/software-architect/_meta.json +1 -0
- package/skills/expert/software-engineer/SKILL.md +437 -0
- package/skills/expert/software-engineer/_meta.json +1 -0
- package/skills/expert/software-engineer/architecture.md +130 -0
- package/skills/expert/software-engineer/patterns.md +151 -0
- package/skills/expert/software-engineer/testing.md +135 -0
- package/skills/expert/system-architect/SKILL.md +628 -0
- package/skills/expert/system-architect/_meta.json +1 -0
- package/skills/expert/system-architect/assets/templates/ARCHITECTURE.md +25 -0
- package/skills/expert/system-architect/assets/templates/README.md +44 -0
- package/skills/expert/system-architect/references/js-ts-standards.md +18 -0
- package/skills/expert/system-architect/references/python-standards.md +19 -0
- package/skills/expert/system-architect/references/scaffolding.md +61 -0
- package/skills/expert/system-architect/references/security-checklist.md +21 -0
- package/skills/openspec/openspec-apply-change/SKILL.md +156 -0
- package/skills/openspec/openspec-apply-change/_meta.json +1 -0
- package/skills/openspec/openspec-archive-change/SKILL.md +114 -0
- package/skills/openspec/openspec-archive-change/_meta.json +1 -0
- package/skills/openspec/openspec-bulk-archive-change/SKILL.md +246 -0
- package/skills/openspec/openspec-bulk-archive-change/_meta.json +1 -0
- package/skills/openspec/openspec-continue-change/SKILL.md +118 -0
- package/skills/openspec/openspec-continue-change/_meta.json +1 -0
- package/skills/openspec/openspec-explore/SKILL.md +288 -0
- package/skills/openspec/openspec-explore/_meta.json +1 -0
- package/skills/openspec/openspec-ff-change/SKILL.md +101 -0
- package/skills/openspec/openspec-ff-change/_meta.json +1 -0
- package/skills/openspec/openspec-new-change/SKILL.md +74 -0
- package/skills/openspec/openspec-new-change/_meta.json +1 -0
- package/skills/openspec/openspec-onboard/SKILL.md +554 -0
- package/skills/openspec/openspec-onboard/_meta.json +1 -0
- package/skills/openspec/openspec-sync-specs/SKILL.md +138 -0
- package/skills/openspec/openspec-sync-specs/_meta.json +1 -0
- package/skills/openspec/openspec-verify-change/SKILL.md +168 -0
- package/skills/openspec/openspec-verify-change/_meta.json +1 -0
- package/skills/pr/pdd-multi-review/SKILL.md +534 -0
- package/skills/pr/pdd-multi-review/_meta.json +1 -0
- package/skills/pr/pdd-pr-batch/SKILL.md +303 -0
- package/skills/pr/pdd-pr-batch/_meta.json +1 -0
- package/skills/pr/pdd-pr-create/SKILL.md +344 -0
- package/skills/pr/pdd-pr-create/_meta.json +1 -0
- package/skills/pr/pdd-pr-merge/SKILL.md +286 -0
- package/skills/pr/pdd-pr-merge/_meta.json +1 -0
- package/skills/pr/pdd-pr-review/SKILL.md +217 -0
- package/skills/pr/pdd-pr-review/_meta.json +1 -0
- package/skills/pr/pdd-task-manager/SKILL.md +636 -0
- package/skills/pr/pdd-task-manager/_meta.json +1 -0
- package/skills/pr/pdd-template-engine/SKILL.md +306 -0
- package/skills/pr/pdd-template-engine/_meta.json +1 -0
- package/templates/behavior-shaping/iron-law-template.md +87 -0
- package/templates/behavior-shaping/rationalization-template.md +62 -0
- package/templates/behavior-shaping/red-flags-template.md +70 -0
- package/templates/bilingual-template.md +139 -0
- package/templates/config/default.yaml +47 -0
- package/templates/project/default/README.md +31 -0
- package/templates/project/frontend/README.md +46 -0
- package/templates/project/java/README.md +48 -0
|
@@ -0,0 +1,605 @@
|
|
|
1
|
+
# Code Smells Reference
|
|
2
|
+
|
|
3
|
+
A comprehensive guide to identifying and fixing code smells, based on Martin Fowler's "Refactoring".
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
1. [Method-Level Smells](#1-method-level-smells)
|
|
8
|
+
2. [Class-Level Smells](#2-class-level-smells)
|
|
9
|
+
3. [Relationship Smells](#3-relationship-smells)
|
|
10
|
+
4. [Other Smells](#4-other-smells)
|
|
11
|
+
5. [Smell Detection Checklist](#5-smell-detection-checklist)
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 1. Method-Level Smells
|
|
16
|
+
|
|
17
|
+
### Duplicated Code
|
|
18
|
+
|
|
19
|
+
**Detection**:
|
|
20
|
+
- Same code structure in multiple places
|
|
21
|
+
- Similar code with minor variations
|
|
22
|
+
- Copy-paste programming
|
|
23
|
+
|
|
24
|
+
**Problems**:
|
|
25
|
+
- Changes must be made in multiple places
|
|
26
|
+
- Risk of inconsistent changes
|
|
27
|
+
- Increased maintenance burden
|
|
28
|
+
|
|
29
|
+
**Solutions**:
|
|
30
|
+
| Situation | Refactoring |
|
|
31
|
+
|-----------|-------------|
|
|
32
|
+
| Same method in same class | Extract Method |
|
|
33
|
+
| Same method in sibling classes | Pull Up Method |
|
|
34
|
+
| Same method in unrelated classes | Extract Class |
|
|
35
|
+
| Similar but not identical | Form Template Method |
|
|
36
|
+
|
|
37
|
+
**Example**:
|
|
38
|
+
```java
|
|
39
|
+
// Smell
|
|
40
|
+
public class Order {
|
|
41
|
+
public double calculateTotal() {
|
|
42
|
+
double total = 0;
|
|
43
|
+
for (Item item : items) {
|
|
44
|
+
total += item.getPrice() * item.getQuantity();
|
|
45
|
+
}
|
|
46
|
+
return total;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
public class Invoice {
|
|
51
|
+
public double calculateAmount() {
|
|
52
|
+
double amount = 0;
|
|
53
|
+
for (Item item : items) {
|
|
54
|
+
amount += item.getPrice() * item.getQuantity();
|
|
55
|
+
}
|
|
56
|
+
return amount;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Fixed
|
|
61
|
+
public class ItemCalculator {
|
|
62
|
+
public double calculateSum(List<Item> items) {
|
|
63
|
+
return items.stream()
|
|
64
|
+
.mapToDouble(i -> i.getPrice() * i.getQuantity())
|
|
65
|
+
.sum();
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
### Long Method
|
|
73
|
+
|
|
74
|
+
**Detection**:
|
|
75
|
+
- Method exceeds 20 lines
|
|
76
|
+
- Requires comments to explain sections
|
|
77
|
+
- Deep nesting (3+ levels)
|
|
78
|
+
- Multiple responsibilities
|
|
79
|
+
|
|
80
|
+
**Problems**:
|
|
81
|
+
- Hard to understand
|
|
82
|
+
- Hard to test
|
|
83
|
+
- Hard to reuse
|
|
84
|
+
- Hard to name
|
|
85
|
+
|
|
86
|
+
**Solutions**:
|
|
87
|
+
| Situation | Refactoring |
|
|
88
|
+
|-----------|-------------|
|
|
89
|
+
| Logical code block | Extract Method |
|
|
90
|
+
| Complex conditional | Decompose Conditional |
|
|
91
|
+
| Long loop body | Extract Method |
|
|
92
|
+
| Many temporary variables | Replace Temp with Query |
|
|
93
|
+
| Too many parameters | Introduce Parameter Object |
|
|
94
|
+
|
|
95
|
+
**Metrics**:
|
|
96
|
+
- **Good**: < 10 lines
|
|
97
|
+
- **Acceptable**: 10-20 lines
|
|
98
|
+
- **Warning**: 20-50 lines
|
|
99
|
+
- **Critical**: > 50 lines
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
### Long Parameter List
|
|
104
|
+
|
|
105
|
+
**Detection**:
|
|
106
|
+
- More than 3-4 parameters
|
|
107
|
+
- Parameters often passed together
|
|
108
|
+
- Difficult to remember order
|
|
109
|
+
|
|
110
|
+
**Problems**:
|
|
111
|
+
- Hard to use correctly
|
|
112
|
+
- Hard to read
|
|
113
|
+
- Hard to maintain
|
|
114
|
+
- Often indicates missing abstraction
|
|
115
|
+
|
|
116
|
+
**Solutions**:
|
|
117
|
+
| Situation | Refactoring |
|
|
118
|
+
|-----------|-------------|
|
|
119
|
+
| Parameters from same object | Preserve Whole Object |
|
|
120
|
+
| Parameters always together | Introduce Parameter Object |
|
|
121
|
+
| Can be derived | Replace Parameter with Method |
|
|
122
|
+
| Flag parameter | Replace Parameter with Explicit Methods |
|
|
123
|
+
|
|
124
|
+
**Example**:
|
|
125
|
+
```java
|
|
126
|
+
// Smell
|
|
127
|
+
void printReport(Date start, Date end, String title,
|
|
128
|
+
String author, String department, boolean summary);
|
|
129
|
+
|
|
130
|
+
// Fixed
|
|
131
|
+
class ReportParameters {
|
|
132
|
+
Date start;
|
|
133
|
+
Date end;
|
|
134
|
+
String title;
|
|
135
|
+
String author;
|
|
136
|
+
String department;
|
|
137
|
+
boolean summary;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
void printReport(ReportParameters params);
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
### Switch Statements
|
|
146
|
+
|
|
147
|
+
**Detection**:
|
|
148
|
+
- Large switch/case blocks
|
|
149
|
+
- Switch on type codes
|
|
150
|
+
- Repeated switch on same variable
|
|
151
|
+
|
|
152
|
+
**Problems**:
|
|
153
|
+
- Violates Open/Closed Principle
|
|
154
|
+
- Changes require modifying switch
|
|
155
|
+
- Often duplicated across codebase
|
|
156
|
+
|
|
157
|
+
**Solutions**:
|
|
158
|
+
| Situation | Refactoring |
|
|
159
|
+
|-----------|-------------|
|
|
160
|
+
| Switch on type | Replace Conditional with Polymorphism |
|
|
161
|
+
| Switch in multiple places | Move Method + Replace Conditional |
|
|
162
|
+
| Simple type switching | Replace Type Code with Subclasses |
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## 2. Class-Level Smells
|
|
167
|
+
|
|
168
|
+
### Large Class
|
|
169
|
+
|
|
170
|
+
**Detection**:
|
|
171
|
+
- Class exceeds 300 lines
|
|
172
|
+
- More than 10 instance variables
|
|
173
|
+
- More than 20 methods
|
|
174
|
+
- Multiple responsibilities
|
|
175
|
+
|
|
176
|
+
**Problems**:
|
|
177
|
+
- Violates Single Responsibility Principle
|
|
178
|
+
- Hard to understand
|
|
179
|
+
- Hard to test
|
|
180
|
+
- High coupling
|
|
181
|
+
|
|
182
|
+
**Solutions**:
|
|
183
|
+
| Situation | Refactoring |
|
|
184
|
+
|-----------|-------------|
|
|
185
|
+
| Distinct responsibilities | Extract Class |
|
|
186
|
+
| Subclass only uses some features | Extract Subclass |
|
|
187
|
+
| Common interface | Extract Interface |
|
|
188
|
+
| Large data class | Extract Class for behavior |
|
|
189
|
+
|
|
190
|
+
**Metrics**:
|
|
191
|
+
- **Good**: < 100 lines, < 5 fields
|
|
192
|
+
- **Acceptable**: 100-200 lines, 5-10 fields
|
|
193
|
+
- **Warning**: 200-300 lines, 10-15 fields
|
|
194
|
+
- **Critical**: > 300 lines, > 15 fields
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
### Divergent Change
|
|
199
|
+
|
|
200
|
+
**Detection**:
|
|
201
|
+
- One class changes for multiple reasons
|
|
202
|
+
- Different types of changes affect same class
|
|
203
|
+
- Class has multiple "axes of change"
|
|
204
|
+
|
|
205
|
+
**Problems**:
|
|
206
|
+
- Violates Single Responsibility Principle
|
|
207
|
+
- Changes are risky
|
|
208
|
+
- Difficult to understand
|
|
209
|
+
|
|
210
|
+
**Solutions**:
|
|
211
|
+
- Extract Class for each responsibility
|
|
212
|
+
- Identify different reasons for change
|
|
213
|
+
- Separate concerns
|
|
214
|
+
|
|
215
|
+
**Example**:
|
|
216
|
+
```java
|
|
217
|
+
// Smell: Employee changes for pay, reporting, AND persistence
|
|
218
|
+
public class Employee {
|
|
219
|
+
// Pay calculation
|
|
220
|
+
public double calculatePay() { }
|
|
221
|
+
public double calculateTax() { }
|
|
222
|
+
|
|
223
|
+
// Reporting
|
|
224
|
+
public String generateReport() { }
|
|
225
|
+
public void printReport() { }
|
|
226
|
+
|
|
227
|
+
// Persistence
|
|
228
|
+
public void save() { }
|
|
229
|
+
public void load() { }
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// Fixed: Separate responsibilities
|
|
233
|
+
public class Employee {
|
|
234
|
+
private EmployeeData data;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
public class PayCalculator { }
|
|
238
|
+
public class EmployeeReporter { }
|
|
239
|
+
public class EmployeeRepository { }
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
### Shotgun Surgery
|
|
245
|
+
|
|
246
|
+
**Detection**:
|
|
247
|
+
- One change requires modifying many classes
|
|
248
|
+
- Each class only needs small change
|
|
249
|
+
- Changes scattered across codebase
|
|
250
|
+
|
|
251
|
+
**Problems**:
|
|
252
|
+
- Easy to miss a change
|
|
253
|
+
- Difficult to track all changes
|
|
254
|
+
- High coupling across classes
|
|
255
|
+
|
|
256
|
+
**Solutions**:
|
|
257
|
+
| Situation | Refactoring |
|
|
258
|
+
|-----------|-------------|
|
|
259
|
+
| Feature spread across classes | Move Method |
|
|
260
|
+
| Small classes doing little | Inline Class |
|
|
261
|
+
| Common functionality | Extract Class |
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
### Feature Envy
|
|
266
|
+
|
|
267
|
+
**Detection**:
|
|
268
|
+
- Method uses another class's data more than its own
|
|
269
|
+
- Method calls many getters on another object
|
|
270
|
+
- Method belongs in another class
|
|
271
|
+
|
|
272
|
+
**Problems**:
|
|
273
|
+
- Misplaced responsibility
|
|
274
|
+
- Increased coupling
|
|
275
|
+
- Violates encapsulation
|
|
276
|
+
|
|
277
|
+
**Solutions**:
|
|
278
|
+
- Move Method to the class it envies
|
|
279
|
+
- Extract Method if only part should move
|
|
280
|
+
|
|
281
|
+
**Example**:
|
|
282
|
+
```java
|
|
283
|
+
// Smell
|
|
284
|
+
class Order {
|
|
285
|
+
public double calculateDiscount(Customer customer) {
|
|
286
|
+
return customer.getPoints() > 100 ?
|
|
287
|
+
customer.getOrderTotal() * 0.1 : 0;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// Fixed
|
|
292
|
+
class Customer {
|
|
293
|
+
public double calculateDiscount() {
|
|
294
|
+
return points > 100 ? orderTotal * 0.1 : 0;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
---
|
|
300
|
+
|
|
301
|
+
### Data Class
|
|
302
|
+
|
|
303
|
+
**Detection**:
|
|
304
|
+
- Class has only fields and getters/setters
|
|
305
|
+
- No business logic
|
|
306
|
+
- Other classes manipulate the data
|
|
307
|
+
|
|
308
|
+
**Problems**:
|
|
309
|
+
- Anemic domain model
|
|
310
|
+
- Behavior separated from data
|
|
311
|
+
- Procedural code in OO clothing
|
|
312
|
+
|
|
313
|
+
**Solutions**:
|
|
314
|
+
- Encapsulate Collection
|
|
315
|
+
- Move behavior to data class
|
|
316
|
+
- Hide setters if possible
|
|
317
|
+
|
|
318
|
+
---
|
|
319
|
+
|
|
320
|
+
## 3. Relationship Smells
|
|
321
|
+
|
|
322
|
+
### Inappropriate Intimacy
|
|
323
|
+
|
|
324
|
+
**Detection**:
|
|
325
|
+
- Classes access each other's private parts
|
|
326
|
+
- Too much knowledge of each other's internals
|
|
327
|
+
- Tight coupling between classes
|
|
328
|
+
|
|
329
|
+
**Problems**:
|
|
330
|
+
- Fragile code
|
|
331
|
+
- Changes ripple
|
|
332
|
+
- Hard to understand dependencies
|
|
333
|
+
|
|
334
|
+
**Solutions**:
|
|
335
|
+
| Situation | Refactoring |
|
|
336
|
+
|-----------|-------------|
|
|
337
|
+
| Accessing private fields | Move Method |
|
|
338
|
+
| Two-way navigation | Change Bidirectional to Unidirectional |
|
|
339
|
+
| Subclass knows parent internals | Replace Inheritance with Delegation |
|
|
340
|
+
|
|
341
|
+
---
|
|
342
|
+
|
|
343
|
+
### Message Chains
|
|
344
|
+
|
|
345
|
+
**Detection**:
|
|
346
|
+
- Long chains of method calls: `a.b().c().d()`
|
|
347
|
+
- Client knows structure of object graph
|
|
348
|
+
- Deep knowledge of relationships
|
|
349
|
+
|
|
350
|
+
**Problems**:
|
|
351
|
+
- Tight coupling to structure
|
|
352
|
+
- Changes in chain break client
|
|
353
|
+
- Law of Demeter violation
|
|
354
|
+
|
|
355
|
+
**Solutions**:
|
|
356
|
+
- Hide Delegate
|
|
357
|
+
- Extract Method to hide chain
|
|
358
|
+
|
|
359
|
+
**Example**:
|
|
360
|
+
```java
|
|
361
|
+
// Smell
|
|
362
|
+
manager = department.getManager().getContactInfo().getPhoneNumber();
|
|
363
|
+
|
|
364
|
+
// Fixed
|
|
365
|
+
manager = department.getManagerPhone();
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
---
|
|
369
|
+
|
|
370
|
+
### Middle Man
|
|
371
|
+
|
|
372
|
+
**Detection**:
|
|
373
|
+
- Class mostly delegates to another
|
|
374
|
+
- Simple pass-through methods
|
|
375
|
+
- No real behavior
|
|
376
|
+
|
|
377
|
+
**Problems**:
|
|
378
|
+
- Unnecessary indirection
|
|
379
|
+
- Bloats codebase
|
|
380
|
+
- Confuses understanding
|
|
381
|
+
|
|
382
|
+
**Solutions**:
|
|
383
|
+
- Remove Middle Man
|
|
384
|
+
- Inline Method
|
|
385
|
+
- Keep if adding value (caching, validation)
|
|
386
|
+
|
|
387
|
+
---
|
|
388
|
+
|
|
389
|
+
### Parallel Inheritance Hierarchies
|
|
390
|
+
|
|
391
|
+
**Detection**:
|
|
392
|
+
- Creating subclass in one hierarchy forces creating in another
|
|
393
|
+
- Hierarchies mirror each other
|
|
394
|
+
|
|
395
|
+
**Problems**:
|
|
396
|
+
- Shotgun surgery for hierarchy changes
|
|
397
|
+
- Tight coupling between hierarchies
|
|
398
|
+
|
|
399
|
+
**Solutions**:
|
|
400
|
+
- Move methods to associate hierarchies
|
|
401
|
+
- Use composition instead of inheritance
|
|
402
|
+
|
|
403
|
+
---
|
|
404
|
+
|
|
405
|
+
## 4. Other Smells
|
|
406
|
+
|
|
407
|
+
### Primitive Obsession
|
|
408
|
+
|
|
409
|
+
**Detection**:
|
|
410
|
+
- Overuse of primitives (String, int, etc.)
|
|
411
|
+
- Multiple parameters of same primitive type
|
|
412
|
+
- Constants representing types
|
|
413
|
+
|
|
414
|
+
**Problems**:
|
|
415
|
+
- No type safety
|
|
416
|
+
- No encapsulation
|
|
417
|
+
- Easy to mix up values
|
|
418
|
+
|
|
419
|
+
**Solutions**:
|
|
420
|
+
- Replace Data Value with Object
|
|
421
|
+
- Replace Type Code with Class
|
|
422
|
+
- Introduce Parameter Object
|
|
423
|
+
|
|
424
|
+
**Example**:
|
|
425
|
+
```java
|
|
426
|
+
// Smell
|
|
427
|
+
void setTemperature(double value, String unit);
|
|
428
|
+
|
|
429
|
+
// Fixed
|
|
430
|
+
void setTemperature(Temperature temp);
|
|
431
|
+
|
|
432
|
+
class Temperature {
|
|
433
|
+
private double value;
|
|
434
|
+
private TemperatureUnit unit;
|
|
435
|
+
}
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
---
|
|
439
|
+
|
|
440
|
+
### Lazy Class
|
|
441
|
+
|
|
442
|
+
**Detection**:
|
|
443
|
+
- Class doing almost nothing
|
|
444
|
+
- Could be inlined
|
|
445
|
+
- No real purpose
|
|
446
|
+
|
|
447
|
+
**Problems**:
|
|
448
|
+
- Unnecessary complexity
|
|
449
|
+
- Maintenance overhead
|
|
450
|
+
- Confuses design
|
|
451
|
+
|
|
452
|
+
**Solutions**:
|
|
453
|
+
- Inline Class
|
|
454
|
+
- Merge with related class
|
|
455
|
+
|
|
456
|
+
---
|
|
457
|
+
|
|
458
|
+
### Speculative Generality
|
|
459
|
+
|
|
460
|
+
**Detection**:
|
|
461
|
+
- Abstract classes with one implementation
|
|
462
|
+
- Unused parameters
|
|
463
|
+
- "Future-proof" hooks
|
|
464
|
+
|
|
465
|
+
**Problems**:
|
|
466
|
+
- Unnecessary complexity
|
|
467
|
+
- Harder to understand
|
|
468
|
+
- Maintenance burden
|
|
469
|
+
|
|
470
|
+
**Solutions**:
|
|
471
|
+
- Collapse Hierarchy
|
|
472
|
+
- Inline Class
|
|
473
|
+
- Remove unused code
|
|
474
|
+
|
|
475
|
+
---
|
|
476
|
+
|
|
477
|
+
### Temporary Field
|
|
478
|
+
|
|
479
|
+
**Detection**:
|
|
480
|
+
- Instance variables only set in certain circumstances
|
|
481
|
+
- Object has "partial" states
|
|
482
|
+
- Null checks for fields
|
|
483
|
+
|
|
484
|
+
**Problems**:
|
|
485
|
+
- Confusing code
|
|
486
|
+
- Hard to understand valid states
|
|
487
|
+
- Often indicates missing class
|
|
488
|
+
|
|
489
|
+
**Solutions**:
|
|
490
|
+
- Extract Class
|
|
491
|
+
- Introduce Null Object
|
|
492
|
+
|
|
493
|
+
---
|
|
494
|
+
|
|
495
|
+
### Refused Bequest
|
|
496
|
+
|
|
497
|
+
**Detection**:
|
|
498
|
+
- Subclass doesn't use inherited methods
|
|
499
|
+
- Subclass overrides to do nothing
|
|
500
|
+
- "Is-a" relationship doesn't hold
|
|
501
|
+
|
|
502
|
+
**Problems**:
|
|
503
|
+
- Incorrect inheritance
|
|
504
|
+
- Confusing hierarchy
|
|
505
|
+
- LSP violation
|
|
506
|
+
|
|
507
|
+
**Solutions**:
|
|
508
|
+
- Push Down Method
|
|
509
|
+
- Replace Inheritance with Delegation
|
|
510
|
+
|
|
511
|
+
---
|
|
512
|
+
|
|
513
|
+
### Comments
|
|
514
|
+
|
|
515
|
+
**Detection**:
|
|
516
|
+
- Comments explaining "what" instead of "why"
|
|
517
|
+
- Commented-out code
|
|
518
|
+
- Long comment blocks
|
|
519
|
+
|
|
520
|
+
**Problems**:
|
|
521
|
+
- Often indicates code smell
|
|
522
|
+
- Comments can become outdated
|
|
523
|
+
- Can mask bad code
|
|
524
|
+
|
|
525
|
+
**Solutions**:
|
|
526
|
+
- Extract Method instead of explaining
|
|
527
|
+
- Rename to make code self-documenting
|
|
528
|
+
- Delete commented-out code
|
|
529
|
+
|
|
530
|
+
**Note**: Good comments explain "why", not "what".
|
|
531
|
+
|
|
532
|
+
---
|
|
533
|
+
|
|
534
|
+
## 5. Smell Detection Checklist
|
|
535
|
+
|
|
536
|
+
### Quick Scan Checklist
|
|
537
|
+
|
|
538
|
+
```
|
|
539
|
+
□ Any method over 20 lines?
|
|
540
|
+
□ Any class over 300 lines?
|
|
541
|
+
□ Any duplicated code?
|
|
542
|
+
□ Any switch statements?
|
|
543
|
+
□ Any method with > 4 parameters?
|
|
544
|
+
□ Any class with > 10 fields?
|
|
545
|
+
□ Any deep inheritance (> 3 levels)?
|
|
546
|
+
□ Any long message chains?
|
|
547
|
+
□ Any data-only classes?
|
|
548
|
+
□ Any lazy classes?
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
### Severity Classification
|
|
552
|
+
|
|
553
|
+
| Severity | Description | Action |
|
|
554
|
+
|----------|-------------|--------|
|
|
555
|
+
| **Critical** | Causes bugs, blocks development | Fix immediately |
|
|
556
|
+
| **High** | Significant maintenance burden | Fix soon |
|
|
557
|
+
| **Medium** | Reduces code quality | Fix when working in area |
|
|
558
|
+
| **Low** | Minor improvement | Fix opportunistically |
|
|
559
|
+
|
|
560
|
+
### Smell → Refactoring Quick Reference
|
|
561
|
+
|
|
562
|
+
| Smell | Primary Refactoring | Alternative |
|
|
563
|
+
|-------|---------------------|-------------|
|
|
564
|
+
| Duplicated Code | Extract Method | Pull Up Method |
|
|
565
|
+
| Long Method | Extract Method | Replace Temp with Query |
|
|
566
|
+
| Large Class | Extract Class | Extract Subclass |
|
|
567
|
+
| Long Parameter List | Introduce Parameter Object | Preserve Whole Object |
|
|
568
|
+
| Divergent Change | Extract Class | - |
|
|
569
|
+
| Shotgun Surgery | Move Method | Inline Class |
|
|
570
|
+
| Feature Envy | Move Method | - |
|
|
571
|
+
| Data Clumps | Extract Class | Introduce Parameter Object |
|
|
572
|
+
| Primitive Obsession | Replace Data Value with Object | - |
|
|
573
|
+
| Switch Statements | Replace with Polymorphism | - |
|
|
574
|
+
| Parallel Inheritance | Move Method | - |
|
|
575
|
+
| Lazy Class | Inline Class | - |
|
|
576
|
+
| Speculative Generality | Inline Class | Collapse Hierarchy |
|
|
577
|
+
| Temporary Field | Extract Class | Introduce Null Object |
|
|
578
|
+
| Message Chains | Hide Delegate | - |
|
|
579
|
+
| Middle Man | Remove Middle Man | - |
|
|
580
|
+
| Inappropriate Intimacy | Move Method | Change Bidirectional |
|
|
581
|
+
| Alternative Classes | Rename Method | - |
|
|
582
|
+
| Incomplete Library Class | Introduce Foreign Method | Introduce Local Extension |
|
|
583
|
+
| Data Class | Encapsulate Collection | Move Method |
|
|
584
|
+
| Refused Bequest | Push Down Method | Replace Inheritance |
|
|
585
|
+
| Comments | Extract Method | Rename |
|
|
586
|
+
|
|
587
|
+
### Detection Tools
|
|
588
|
+
|
|
589
|
+
**IDE Warnings**:
|
|
590
|
+
- Method length warnings
|
|
591
|
+
- Parameter count warnings
|
|
592
|
+
- Cyclomatic complexity warnings
|
|
593
|
+
|
|
594
|
+
**Static Analysis**:
|
|
595
|
+
- SonarQube
|
|
596
|
+
- PMD
|
|
597
|
+
- Checkstyle
|
|
598
|
+
- ESLint (JavaScript)
|
|
599
|
+
- Pylint (Python)
|
|
600
|
+
|
|
601
|
+
**Metrics to Monitor**:
|
|
602
|
+
- Lines of Code (LOC)
|
|
603
|
+
- Cyclomatic Complexity
|
|
604
|
+
- Coupling Between Objects (CBO)
|
|
605
|
+
- Lack of Cohesion of Methods (LCOM)
|