agentic-qe 1.1.0 → 1.2.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/.claude/agents/qe-coverage-analyzer.md +8 -0
- package/.claude/agents/qe-flaky-test-hunter.md +9 -1
- package/.claude/agents/qe-test-generator.md +7 -0
- package/.claude/agents/reasoning/agent.md +816 -0
- package/.claude/agents/reasoning/goal-planner.md +73 -0
- package/.claude/settings.json +21 -20
- package/.claude/skills/README.md +124 -0
- package/.claude/skills/agentdb-advanced/SKILL.md +550 -0
- package/.claude/skills/agentdb-learning/SKILL.md +545 -0
- package/.claude/skills/agentdb-memory-patterns/SKILL.md +339 -0
- package/.claude/skills/agentdb-optimization/SKILL.md +509 -0
- package/.claude/skills/agentdb-vector-search/SKILL.md +339 -0
- package/.claude/skills/agentic-quality-engineering/SKILL.md +604 -0
- package/.claude/skills/api-testing-patterns/SKILL.md +686 -0
- package/.claude/skills/bug-reporting-excellence/SKILL.md +632 -0
- package/.claude/skills/code-review-quality/SKILL.md +683 -0
- package/.claude/skills/consultancy-practices/SKILL.md +540 -0
- package/.claude/skills/context-driven-testing/SKILL.md +466 -0
- package/.claude/skills/exploratory-testing-advanced/SKILL.md +676 -0
- package/.claude/skills/flow-nexus-neural/SKILL.md +738 -0
- package/.claude/skills/flow-nexus-platform/SKILL.md +1157 -0
- package/.claude/skills/flow-nexus-swarm/SKILL.md +610 -0
- package/.claude/skills/github-code-review/SKILL.md +1140 -0
- package/.claude/skills/github-multi-repo/SKILL.md +874 -0
- package/.claude/skills/github-project-management/SKILL.md +1277 -0
- package/.claude/skills/github-release-management/SKILL.md +1081 -0
- package/.claude/skills/github-workflow-automation/SKILL.md +1065 -0
- package/.claude/skills/hive-mind-advanced/SKILL.md +712 -0
- package/.claude/skills/holistic-testing-pact/SKILL.md +225 -0
- package/.claude/skills/hooks-automation/SKILL.md +1201 -0
- package/.claude/skills/pair-programming/SKILL.md +1202 -0
- package/.claude/skills/performance-analysis/SKILL.md +563 -0
- package/.claude/skills/performance-testing/SKILL.md +662 -0
- package/.claude/skills/quality-metrics/SKILL.md +592 -0
- package/.claude/skills/reasoningbank-agentdb/SKILL.md +446 -0
- package/.claude/skills/reasoningbank-intelligence/SKILL.md +201 -0
- package/.claude/skills/refactoring-patterns/SKILL.md +778 -0
- package/.claude/skills/risk-based-testing/SKILL.md +721 -0
- package/.claude/skills/security-testing/SKILL.md +651 -0
- package/.claude/skills/skill-builder/SKILL.md +910 -0
- package/.claude/skills/sparc-methodology/SKILL.md +1115 -0
- package/.claude/skills/stream-chain/SKILL.md +563 -0
- package/.claude/skills/swarm-advanced/SKILL.md +973 -0
- package/.claude/skills/swarm-orchestration/SKILL.md +179 -0
- package/.claude/skills/tdd-london-chicago/SKILL.md +567 -0
- package/.claude/skills/technical-writing/SKILL.md +235 -0
- package/.claude/skills/test-automation-strategy/SKILL.md +842 -0
- package/.claude/skills/verification-quality/SKILL.md +649 -0
- package/.claude/skills/xp-practices/SKILL.md +671 -0
- package/.claude/statusline-command.sh +176 -0
- package/CHANGELOG.md +536 -1
- package/README.md +92 -3
- package/config/improvement-loop.config.ts +323 -0
- package/config/neural-agent.config.ts +197 -0
- package/dist/adapters/MemoryStoreAdapter.d.ts +16 -16
- package/dist/adapters/MemoryStoreAdapter.d.ts.map +1 -1
- package/dist/adapters/MemoryStoreAdapter.js +16 -16
- package/dist/adapters/MemoryStoreAdapter.js.map +1 -1
- package/dist/agents/BaseAgent.d.ts +69 -0
- package/dist/agents/BaseAgent.d.ts.map +1 -1
- package/dist/agents/BaseAgent.js +382 -1
- package/dist/agents/BaseAgent.js.map +1 -1
- package/dist/agents/CoverageAnalyzerAgent.d.ts +13 -2
- package/dist/agents/CoverageAnalyzerAgent.d.ts.map +1 -1
- package/dist/agents/CoverageAnalyzerAgent.js +105 -6
- package/dist/agents/CoverageAnalyzerAgent.js.map +1 -1
- package/dist/agents/DeploymentReadinessAgent.d.ts.map +1 -1
- package/dist/agents/DeploymentReadinessAgent.js +13 -13
- package/dist/agents/DeploymentReadinessAgent.js.map +1 -1
- package/dist/agents/FlakyTestHunterAgent.d.ts +28 -0
- package/dist/agents/FlakyTestHunterAgent.d.ts.map +1 -1
- package/dist/agents/FlakyTestHunterAgent.js +159 -4
- package/dist/agents/FlakyTestHunterAgent.js.map +1 -1
- package/dist/agents/FleetCommanderAgent.d.ts.map +1 -1
- package/dist/agents/FleetCommanderAgent.js +2 -2
- package/dist/agents/FleetCommanderAgent.js.map +1 -1
- package/dist/agents/LearningAgent.d.ts +14 -5
- package/dist/agents/LearningAgent.d.ts.map +1 -1
- package/dist/agents/LearningAgent.js +36 -16
- package/dist/agents/LearningAgent.js.map +1 -1
- package/dist/agents/NeuralAgentExtension.d.ts +117 -0
- package/dist/agents/NeuralAgentExtension.d.ts.map +1 -0
- package/dist/agents/NeuralAgentExtension.js +288 -0
- package/dist/agents/NeuralAgentExtension.js.map +1 -0
- package/dist/agents/PerformanceTesterAgent.d.ts.map +1 -1
- package/dist/agents/PerformanceTesterAgent.js +4 -3
- package/dist/agents/PerformanceTesterAgent.js.map +1 -1
- package/dist/agents/ProductionIntelligenceAgent.js +7 -7
- package/dist/agents/ProductionIntelligenceAgent.js.map +1 -1
- package/dist/agents/QualityAnalyzerAgent.d.ts.map +1 -1
- package/dist/agents/QualityAnalyzerAgent.js +2 -2
- package/dist/agents/QualityAnalyzerAgent.js.map +1 -1
- package/dist/agents/QualityGateAgent.js +5 -5
- package/dist/agents/QualityGateAgent.js.map +1 -1
- package/dist/agents/RegressionRiskAnalyzerAgent.js +7 -7
- package/dist/agents/RegressionRiskAnalyzerAgent.js.map +1 -1
- package/dist/agents/RequirementsValidatorAgent.d.ts.map +1 -1
- package/dist/agents/RequirementsValidatorAgent.js +1 -1
- package/dist/agents/RequirementsValidatorAgent.js.map +1 -1
- package/dist/agents/SecurityScannerAgent.js +6 -6
- package/dist/agents/SecurityScannerAgent.js.map +1 -1
- package/dist/agents/TestExecutorAgent.d.ts.map +1 -1
- package/dist/agents/TestExecutorAgent.js +1 -3
- package/dist/agents/TestExecutorAgent.js.map +1 -1
- package/dist/agents/TestGeneratorAgent.d.ts +15 -4
- package/dist/agents/TestGeneratorAgent.d.ts.map +1 -1
- package/dist/agents/TestGeneratorAgent.js +165 -43
- package/dist/agents/TestGeneratorAgent.js.map +1 -1
- package/dist/agents/mixins/NeuralCapableMixin.d.ts +130 -0
- package/dist/agents/mixins/NeuralCapableMixin.d.ts.map +1 -0
- package/dist/agents/mixins/NeuralCapableMixin.js +358 -0
- package/dist/agents/mixins/NeuralCapableMixin.js.map +1 -0
- package/dist/agents/mixins/QUICCapableMixin.d.ts +34 -0
- package/dist/agents/mixins/QUICCapableMixin.d.ts.map +1 -0
- package/dist/agents/mixins/QUICCapableMixin.js +346 -0
- package/dist/agents/mixins/QUICCapableMixin.js.map +1 -0
- package/dist/cli/commands/agent/index.d.ts +5 -0
- package/dist/cli/commands/agent/index.d.ts.map +1 -1
- package/dist/cli/commands/agent/index.js +11 -6
- package/dist/cli/commands/agent/index.js.map +1 -1
- package/dist/cli/commands/agent/kill.d.ts +13 -0
- package/dist/cli/commands/agent/kill.d.ts.map +1 -0
- package/dist/cli/commands/agent/kill.js +65 -0
- package/dist/cli/commands/agent/kill.js.map +1 -0
- package/dist/cli/commands/agent/list.d.ts +19 -0
- package/dist/cli/commands/agent/list.d.ts.map +1 -0
- package/dist/cli/commands/agent/list.js +92 -0
- package/dist/cli/commands/agent/list.js.map +1 -0
- package/dist/cli/commands/agent/logs.d.ts +14 -0
- package/dist/cli/commands/agent/logs.d.ts.map +1 -0
- package/dist/cli/commands/agent/logs.js +77 -0
- package/dist/cli/commands/agent/logs.js.map +1 -0
- package/dist/cli/commands/agent/metrics.d.ts +21 -0
- package/dist/cli/commands/agent/metrics.d.ts.map +1 -0
- package/dist/cli/commands/agent/metrics.js +87 -0
- package/dist/cli/commands/agent/metrics.js.map +1 -0
- package/dist/cli/commands/agent/spawn.d.ts +28 -0
- package/dist/cli/commands/agent/spawn.d.ts.map +1 -0
- package/dist/cli/commands/agent/spawn.js +83 -0
- package/dist/cli/commands/agent/spawn.js.map +1 -0
- package/dist/cli/commands/init.d.ts +24 -0
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +475 -7
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/skills/index.d.ts +51 -0
- package/dist/cli/commands/skills/index.d.ts.map +1 -0
- package/dist/cli/commands/skills/index.js +364 -0
- package/dist/cli/commands/skills/index.js.map +1 -0
- package/dist/cli/index.js +92 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/core/EventBus.d.ts +38 -0
- package/dist/core/EventBus.d.ts.map +1 -1
- package/dist/core/EventBus.js +176 -31
- package/dist/core/EventBus.js.map +1 -1
- package/dist/core/FleetManager.d.ts +35 -1
- package/dist/core/FleetManager.d.ts.map +1 -1
- package/dist/core/FleetManager.js +121 -45
- package/dist/core/FleetManager.js.map +1 -1
- package/dist/core/MemoryManager.d.ts +19 -1
- package/dist/core/MemoryManager.d.ts.map +1 -1
- package/dist/core/MemoryManager.js +25 -1
- package/dist/core/MemoryManager.js.map +1 -1
- package/dist/core/embeddings/EmbeddingCache.d.ts +134 -0
- package/dist/core/embeddings/EmbeddingCache.d.ts.map +1 -0
- package/dist/core/embeddings/EmbeddingCache.js +239 -0
- package/dist/core/embeddings/EmbeddingCache.js.map +1 -0
- package/dist/core/embeddings/EmbeddingGenerator.d.ts +224 -0
- package/dist/core/embeddings/EmbeddingGenerator.d.ts.map +1 -0
- package/dist/core/embeddings/EmbeddingGenerator.js +459 -0
- package/dist/core/embeddings/EmbeddingGenerator.js.map +1 -0
- package/dist/core/embeddings/index.d.ts +15 -0
- package/dist/core/embeddings/index.d.ts.map +1 -0
- package/dist/core/embeddings/index.js +22 -0
- package/dist/core/embeddings/index.js.map +1 -0
- package/dist/core/memory/AgentDBIntegration.d.ts +35 -0
- package/dist/core/memory/AgentDBIntegration.d.ts.map +1 -0
- package/dist/core/memory/AgentDBIntegration.js +75 -0
- package/dist/core/memory/AgentDBIntegration.js.map +1 -0
- package/dist/core/memory/AgentDBManager.d.ts +200 -0
- package/dist/core/memory/AgentDBManager.d.ts.map +1 -0
- package/dist/core/memory/AgentDBManager.js +263 -0
- package/dist/core/memory/AgentDBManager.js.map +1 -0
- package/dist/core/memory/AgentDBService.d.ts +160 -0
- package/dist/core/memory/AgentDBService.d.ts.map +1 -0
- package/dist/core/memory/AgentDBService.js +450 -0
- package/dist/core/memory/AgentDBService.js.map +1 -0
- package/dist/core/memory/RealAgentDBAdapter.d.ts +51 -0
- package/dist/core/memory/RealAgentDBAdapter.d.ts.map +1 -0
- package/dist/core/memory/RealAgentDBAdapter.js +230 -0
- package/dist/core/memory/RealAgentDBAdapter.js.map +1 -0
- package/dist/core/memory/ReasoningBankAdapter.d.ts +58 -0
- package/dist/core/memory/ReasoningBankAdapter.d.ts.map +1 -0
- package/dist/core/memory/ReasoningBankAdapter.js +80 -0
- package/dist/core/memory/ReasoningBankAdapter.js.map +1 -0
- package/dist/core/memory/SwarmMemoryManager.d.ts +75 -3
- package/dist/core/memory/SwarmMemoryManager.d.ts.map +1 -1
- package/dist/core/memory/SwarmMemoryManager.js +236 -52
- package/dist/core/memory/SwarmMemoryManager.js.map +1 -1
- package/dist/core/memory/index.d.ts +4 -0
- package/dist/core/memory/index.d.ts.map +1 -1
- package/dist/core/memory/index.js +9 -1
- package/dist/core/memory/index.js.map +1 -1
- package/dist/core/neural/NeuralTrainer.d.ts +137 -0
- package/dist/core/neural/NeuralTrainer.d.ts.map +1 -0
- package/dist/core/neural/NeuralTrainer.js +543 -0
- package/dist/core/neural/NeuralTrainer.js.map +1 -0
- package/dist/core/neural/index.d.ts +8 -0
- package/dist/core/neural/index.d.ts.map +1 -0
- package/dist/core/neural/index.js +24 -0
- package/dist/core/neural/index.js.map +1 -0
- package/dist/core/neural/types.d.ts +216 -0
- package/dist/core/neural/types.d.ts.map +1 -0
- package/dist/core/neural/types.js +8 -0
- package/dist/core/neural/types.js.map +1 -0
- package/dist/core/security/CertificateValidator.d.ts +130 -0
- package/dist/core/security/CertificateValidator.d.ts.map +1 -0
- package/dist/core/security/CertificateValidator.js +376 -0
- package/dist/core/security/CertificateValidator.js.map +1 -0
- package/dist/core/transport/QUICTransport.d.ts +62 -0
- package/dist/core/transport/QUICTransport.d.ts.map +1 -0
- package/dist/core/transport/QUICTransport.js +381 -0
- package/dist/core/transport/QUICTransport.js.map +1 -0
- package/dist/core/transport/SecureQUICTransport.d.ts +71 -0
- package/dist/core/transport/SecureQUICTransport.d.ts.map +1 -0
- package/dist/core/transport/SecureQUICTransport.js +253 -0
- package/dist/core/transport/SecureQUICTransport.js.map +1 -0
- package/dist/learning/AdvancedFeatureExtractor.d.ts +123 -0
- package/dist/learning/AdvancedFeatureExtractor.d.ts.map +1 -0
- package/dist/learning/AdvancedFeatureExtractor.js +423 -0
- package/dist/learning/AdvancedFeatureExtractor.js.map +1 -0
- package/dist/learning/FlakyPredictionModel.d.ts +11 -1
- package/dist/learning/FlakyPredictionModel.d.ts.map +1 -1
- package/dist/learning/FlakyPredictionModel.js +82 -35
- package/dist/learning/FlakyPredictionModel.js.map +1 -1
- package/dist/learning/FlakyTestDetector.d.ts +9 -0
- package/dist/learning/FlakyTestDetector.d.ts.map +1 -1
- package/dist/learning/FlakyTestDetector.js +28 -6
- package/dist/learning/FlakyTestDetector.js.map +1 -1
- package/dist/learning/ImprovementLoop.d.ts +16 -2
- package/dist/learning/ImprovementLoop.d.ts.map +1 -1
- package/dist/learning/ImprovementLoop.js +67 -8
- package/dist/learning/ImprovementLoop.js.map +1 -1
- package/dist/learning/ImprovementWorker.d.ts +83 -0
- package/dist/learning/ImprovementWorker.d.ts.map +1 -0
- package/dist/learning/ImprovementWorker.js +164 -0
- package/dist/learning/ImprovementWorker.js.map +1 -0
- package/dist/learning/NeuralPatternMatcher.d.ts +184 -0
- package/dist/learning/NeuralPatternMatcher.d.ts.map +1 -0
- package/dist/learning/NeuralPatternMatcher.js +702 -0
- package/dist/learning/NeuralPatternMatcher.js.map +1 -0
- package/dist/learning/NeuralTrainer.d.ts +209 -0
- package/dist/learning/NeuralTrainer.d.ts.map +1 -0
- package/dist/learning/NeuralTrainer.js +478 -0
- package/dist/learning/NeuralTrainer.js.map +1 -0
- package/dist/learning/index.d.ts +13 -7
- package/dist/learning/index.d.ts.map +1 -1
- package/dist/learning/index.js +27 -11
- package/dist/learning/index.js.map +1 -1
- package/dist/learning/types.d.ts +1 -0
- package/dist/learning/types.d.ts.map +1 -1
- package/dist/learning/types.js +16 -0
- package/dist/learning/types.js.map +1 -1
- package/dist/mcp/MCPToolRegistry.d.ts +34 -0
- package/dist/mcp/MCPToolRegistry.d.ts.map +1 -0
- package/dist/mcp/MCPToolRegistry.js +48 -0
- package/dist/mcp/MCPToolRegistry.js.map +1 -0
- package/dist/mcp/server.d.ts +4 -4
- package/dist/mcp/services/AgentRegistry.d.ts.map +1 -1
- package/dist/mcp/services/AgentRegistry.js +7 -1
- package/dist/mcp/services/AgentRegistry.js.map +1 -1
- package/dist/transport/QUICTransport.d.ts +340 -0
- package/dist/transport/QUICTransport.d.ts.map +1 -0
- package/dist/transport/QUICTransport.js +814 -0
- package/dist/transport/QUICTransport.js.map +1 -0
- package/dist/transport/UDPTransport.d.ts +348 -0
- package/dist/transport/UDPTransport.d.ts.map +1 -0
- package/dist/transport/UDPTransport.js +820 -0
- package/dist/transport/UDPTransport.js.map +1 -0
- package/dist/types/errors.d.ts +1 -1
- package/dist/types/index.d.ts +37 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/quic.d.ts +339 -0
- package/dist/types/quic.d.ts.map +1 -0
- package/dist/types/quic.js +48 -0
- package/dist/types/quic.js.map +1 -0
- package/dist/utils/Config.js +1 -1
- package/dist/utils/Config.js.map +1 -1
- package/dist/utils/Database.d.ts +14 -0
- package/dist/utils/Database.d.ts.map +1 -1
- package/dist/utils/Database.js +51 -4
- package/dist/utils/Database.js.map +1 -1
- package/dist/utils/Logger.d.ts.map +1 -1
- package/dist/utils/Logger.js +111 -26
- package/dist/utils/Logger.js.map +1 -1
- package/package.json +30 -7
|
@@ -0,0 +1,778 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: refactoring-patterns
|
|
3
|
+
description: Apply safe refactoring patterns to improve code structure without changing behavior. Use when cleaning up code, reducing technical debt, or improving maintainability.
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
category: development
|
|
6
|
+
tags: [refactoring, clean-code, technical-debt, code-quality, patterns, design]
|
|
7
|
+
difficulty: intermediate
|
|
8
|
+
estimated_time: 35-50 minutes
|
|
9
|
+
author: user
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# Refactoring Patterns
|
|
13
|
+
|
|
14
|
+
## Core Philosophy
|
|
15
|
+
|
|
16
|
+
Refactoring is changing code structure without changing behavior. Tests are your safety net - refactor fearlessly when you have good tests.
|
|
17
|
+
|
|
18
|
+
**Key principle:** Small steps, frequent commits, always green tests.
|
|
19
|
+
|
|
20
|
+
## When to Refactor
|
|
21
|
+
|
|
22
|
+
### ✅ Refactor When:
|
|
23
|
+
- Adding new feature requires changing messy code
|
|
24
|
+
- Code is hard to test
|
|
25
|
+
- You touch code and don't understand it
|
|
26
|
+
- Duplication becomes obvious (third time)
|
|
27
|
+
- Performance is adequate but code is ugly
|
|
28
|
+
|
|
29
|
+
### ❌ Don't Refactor When:
|
|
30
|
+
- No tests exist (write tests first)
|
|
31
|
+
- Code works and you won't touch it again
|
|
32
|
+
- Deadline is tomorrow (technical debt note, refactor later)
|
|
33
|
+
- You don't understand what the code does yet
|
|
34
|
+
- "Just because" - refactor needs a reason
|
|
35
|
+
|
|
36
|
+
## The Refactoring Cycle
|
|
37
|
+
|
|
38
|
+
**Red → Green → Refactor**
|
|
39
|
+
|
|
40
|
+
1. **Ensure tests pass** (Green)
|
|
41
|
+
2. **Make small change** (Refactor)
|
|
42
|
+
3. **Run tests** (Still Green)
|
|
43
|
+
4. **Commit** (Save progress)
|
|
44
|
+
5. **Repeat**
|
|
45
|
+
|
|
46
|
+
**Never refactor without tests. Never.**
|
|
47
|
+
|
|
48
|
+
## Extract Method
|
|
49
|
+
|
|
50
|
+
**Problem:** Long method doing too much
|
|
51
|
+
|
|
52
|
+
**Before:**
|
|
53
|
+
```javascript
|
|
54
|
+
function processOrder(order) {
|
|
55
|
+
// Validate order
|
|
56
|
+
if (!order.items || order.items.length === 0) {
|
|
57
|
+
throw new Error('Order has no items');
|
|
58
|
+
}
|
|
59
|
+
if (!order.customer || !order.customer.email) {
|
|
60
|
+
throw new Error('Invalid customer');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Calculate total
|
|
64
|
+
let subtotal = 0;
|
|
65
|
+
for (let item of order.items) {
|
|
66
|
+
subtotal += item.price * item.quantity;
|
|
67
|
+
}
|
|
68
|
+
let tax = subtotal * 0.10;
|
|
69
|
+
let total = subtotal + tax;
|
|
70
|
+
|
|
71
|
+
// Save order
|
|
72
|
+
const savedOrder = db.orders.create({
|
|
73
|
+
...order,
|
|
74
|
+
subtotal,
|
|
75
|
+
tax,
|
|
76
|
+
total,
|
|
77
|
+
status: 'pending'
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
// Send email
|
|
81
|
+
emailService.send({
|
|
82
|
+
to: order.customer.email,
|
|
83
|
+
subject: 'Order Confirmation',
|
|
84
|
+
body: `Your order #${savedOrder.id} has been received.`
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
return savedOrder;
|
|
88
|
+
}
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
**After:**
|
|
92
|
+
```javascript
|
|
93
|
+
function processOrder(order) {
|
|
94
|
+
validateOrder(order);
|
|
95
|
+
const pricing = calculatePricing(order);
|
|
96
|
+
const savedOrder = saveOrder(order, pricing);
|
|
97
|
+
sendConfirmationEmail(order.customer.email, savedOrder.id);
|
|
98
|
+
return savedOrder;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function validateOrder(order) {
|
|
102
|
+
if (!order.items || order.items.length === 0) {
|
|
103
|
+
throw new Error('Order has no items');
|
|
104
|
+
}
|
|
105
|
+
if (!order.customer || !order.customer.email) {
|
|
106
|
+
throw new Error('Invalid customer');
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function calculatePricing(order) {
|
|
111
|
+
const subtotal = order.items.reduce((sum, item) =>
|
|
112
|
+
sum + item.price * item.quantity, 0
|
|
113
|
+
);
|
|
114
|
+
const tax = subtotal * 0.10;
|
|
115
|
+
const total = subtotal + tax;
|
|
116
|
+
return { subtotal, tax, total };
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function saveOrder(order, pricing) {
|
|
120
|
+
return db.orders.create({
|
|
121
|
+
...order,
|
|
122
|
+
...pricing,
|
|
123
|
+
status: 'pending'
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function sendConfirmationEmail(email, orderId) {
|
|
128
|
+
emailService.send({
|
|
129
|
+
to: email,
|
|
130
|
+
subject: 'Order Confirmation',
|
|
131
|
+
body: `Your order #${orderId} has been received.`
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
**Benefits:**
|
|
137
|
+
- Each function has single responsibility
|
|
138
|
+
- Easy to test each part independently
|
|
139
|
+
- Clear what the code does at a glance
|
|
140
|
+
|
|
141
|
+
## Extract Class
|
|
142
|
+
|
|
143
|
+
**Problem:** Class doing too much
|
|
144
|
+
|
|
145
|
+
**Before:**
|
|
146
|
+
```javascript
|
|
147
|
+
class Order {
|
|
148
|
+
constructor(items, customer) {
|
|
149
|
+
this.items = items;
|
|
150
|
+
this.customer = customer;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
calculateSubtotal() {
|
|
154
|
+
return this.items.reduce((sum, item) =>
|
|
155
|
+
sum + item.price * item.quantity, 0
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
calculateTax() {
|
|
160
|
+
return this.calculateSubtotal() * 0.10;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
calculateTotal() {
|
|
164
|
+
return this.calculateSubtotal() + this.calculateTax();
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
sendConfirmationEmail() {
|
|
168
|
+
emailService.send({
|
|
169
|
+
to: this.customer.email,
|
|
170
|
+
subject: 'Order Confirmation',
|
|
171
|
+
body: `Your order has been received. Total: $${this.calculateTotal()}`
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
sendShippingNotification() {
|
|
176
|
+
emailService.send({
|
|
177
|
+
to: this.customer.email,
|
|
178
|
+
subject: 'Order Shipped',
|
|
179
|
+
body: `Your order has been shipped.`
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
**After:**
|
|
186
|
+
```javascript
|
|
187
|
+
class Order {
|
|
188
|
+
constructor(items, customer) {
|
|
189
|
+
this.items = items;
|
|
190
|
+
this.customer = customer;
|
|
191
|
+
this.pricing = new OrderPricing(items);
|
|
192
|
+
this.notifications = new OrderNotifications(customer.email);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
getTotal() {
|
|
196
|
+
return this.pricing.calculateTotal();
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
sendConfirmation() {
|
|
200
|
+
this.notifications.sendConfirmation(this.getTotal());
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
sendShippingNotification() {
|
|
204
|
+
this.notifications.sendShipping();
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
class OrderPricing {
|
|
209
|
+
constructor(items) {
|
|
210
|
+
this.items = items;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
calculateSubtotal() {
|
|
214
|
+
return this.items.reduce((sum, item) =>
|
|
215
|
+
sum + item.price * item.quantity, 0
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
calculateTax() {
|
|
220
|
+
return this.calculateSubtotal() * 0.10;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
calculateTotal() {
|
|
224
|
+
return this.calculateSubtotal() + this.calculateTax();
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
class OrderNotifications {
|
|
229
|
+
constructor(email) {
|
|
230
|
+
this.email = email;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
sendConfirmation(total) {
|
|
234
|
+
emailService.send({
|
|
235
|
+
to: this.email,
|
|
236
|
+
subject: 'Order Confirmation',
|
|
237
|
+
body: `Your order has been received. Total: $${total}`
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
sendShipping() {
|
|
242
|
+
emailService.send({
|
|
243
|
+
to: this.email,
|
|
244
|
+
subject: 'Order Shipped',
|
|
245
|
+
body: `Your order has been shipped.`
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
## Replace Conditional with Polymorphism
|
|
252
|
+
|
|
253
|
+
**Problem:** Complex conditionals based on type
|
|
254
|
+
|
|
255
|
+
**Before:**
|
|
256
|
+
```javascript
|
|
257
|
+
class PaymentProcessor {
|
|
258
|
+
processPayment(payment) {
|
|
259
|
+
if (payment.type === 'credit_card') {
|
|
260
|
+
return this.chargeCreditCard(
|
|
261
|
+
payment.cardNumber,
|
|
262
|
+
payment.amount
|
|
263
|
+
);
|
|
264
|
+
} else if (payment.type === 'paypal') {
|
|
265
|
+
return this.chargePayPal(
|
|
266
|
+
payment.paypalAccount,
|
|
267
|
+
payment.amount
|
|
268
|
+
);
|
|
269
|
+
} else if (payment.type === 'crypto') {
|
|
270
|
+
return this.chargeCrypto(
|
|
271
|
+
payment.walletAddress,
|
|
272
|
+
payment.amount
|
|
273
|
+
);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
**After:**
|
|
280
|
+
```javascript
|
|
281
|
+
class PaymentProcessor {
|
|
282
|
+
processPayment(paymentMethod) {
|
|
283
|
+
return paymentMethod.charge();
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
class CreditCardPayment {
|
|
288
|
+
constructor(cardNumber, amount) {
|
|
289
|
+
this.cardNumber = cardNumber;
|
|
290
|
+
this.amount = amount;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
charge() {
|
|
294
|
+
return gateway.chargeCreditCard(this.cardNumber, this.amount);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
class PayPalPayment {
|
|
299
|
+
constructor(account, amount) {
|
|
300
|
+
this.account = account;
|
|
301
|
+
this.amount = amount;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
charge() {
|
|
305
|
+
return gateway.chargePayPal(this.account, this.amount);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
class CryptoPayment {
|
|
310
|
+
constructor(walletAddress, amount) {
|
|
311
|
+
this.walletAddress = walletAddress;
|
|
312
|
+
this.amount = amount;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
charge() {
|
|
316
|
+
return gateway.chargeCrypto(this.walletAddress, this.amount);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
## Introduce Parameter Object
|
|
322
|
+
|
|
323
|
+
**Problem:** Functions with many parameters
|
|
324
|
+
|
|
325
|
+
**Before:**
|
|
326
|
+
```javascript
|
|
327
|
+
function createUser(
|
|
328
|
+
firstName,
|
|
329
|
+
lastName,
|
|
330
|
+
email,
|
|
331
|
+
phoneNumber,
|
|
332
|
+
address,
|
|
333
|
+
city,
|
|
334
|
+
state,
|
|
335
|
+
zipCode,
|
|
336
|
+
country
|
|
337
|
+
) {
|
|
338
|
+
// ...
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
createUser(
|
|
342
|
+
'John',
|
|
343
|
+
'Doe',
|
|
344
|
+
'john@example.com',
|
|
345
|
+
'555-1234',
|
|
346
|
+
'123 Main St',
|
|
347
|
+
'Springfield',
|
|
348
|
+
'IL',
|
|
349
|
+
'62701',
|
|
350
|
+
'USA'
|
|
351
|
+
);
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
**After:**
|
|
355
|
+
```javascript
|
|
356
|
+
class UserProfile {
|
|
357
|
+
constructor(firstName, lastName, contactInfo, address) {
|
|
358
|
+
this.firstName = firstName;
|
|
359
|
+
this.lastName = lastName;
|
|
360
|
+
this.contactInfo = contactInfo;
|
|
361
|
+
this.address = address;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
class ContactInfo {
|
|
366
|
+
constructor(email, phoneNumber) {
|
|
367
|
+
this.email = email;
|
|
368
|
+
this.phoneNumber = phoneNumber;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
class Address {
|
|
373
|
+
constructor(street, city, state, zipCode, country) {
|
|
374
|
+
this.street = street;
|
|
375
|
+
this.city = city;
|
|
376
|
+
this.state = state;
|
|
377
|
+
this.zipCode = zipCode;
|
|
378
|
+
this.country = country;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
function createUser(profile) {
|
|
383
|
+
// ...
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
createUser(new UserProfile(
|
|
387
|
+
'John',
|
|
388
|
+
'Doe',
|
|
389
|
+
new ContactInfo('john@example.com', '555-1234'),
|
|
390
|
+
new Address('123 Main St', 'Springfield', 'IL', '62701', 'USA')
|
|
391
|
+
));
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
## Replace Magic Numbers with Named Constants
|
|
395
|
+
|
|
396
|
+
**Before:**
|
|
397
|
+
```javascript
|
|
398
|
+
function calculateDiscount(price, customerType) {
|
|
399
|
+
if (customerType === 1) {
|
|
400
|
+
return price * 0.10;
|
|
401
|
+
} else if (customerType === 2) {
|
|
402
|
+
return price * 0.20;
|
|
403
|
+
} else if (customerType === 3) {
|
|
404
|
+
return price * 0.30;
|
|
405
|
+
}
|
|
406
|
+
return 0;
|
|
407
|
+
}
|
|
408
|
+
```
|
|
409
|
+
|
|
410
|
+
**After:**
|
|
411
|
+
```javascript
|
|
412
|
+
const CustomerType = {
|
|
413
|
+
STANDARD: 1,
|
|
414
|
+
PREMIUM: 2,
|
|
415
|
+
VIP: 3
|
|
416
|
+
};
|
|
417
|
+
|
|
418
|
+
const DiscountRate = {
|
|
419
|
+
[CustomerType.STANDARD]: 0.10,
|
|
420
|
+
[CustomerType.PREMIUM]: 0.20,
|
|
421
|
+
[CustomerType.VIP]: 0.30
|
|
422
|
+
};
|
|
423
|
+
|
|
424
|
+
function calculateDiscount(price, customerType) {
|
|
425
|
+
const rate = DiscountRate[customerType] || 0;
|
|
426
|
+
return price * rate;
|
|
427
|
+
}
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
## Decompose Conditional
|
|
431
|
+
|
|
432
|
+
**Problem:** Complex conditional logic
|
|
433
|
+
|
|
434
|
+
**Before:**
|
|
435
|
+
```javascript
|
|
436
|
+
if (
|
|
437
|
+
order.total > 1000 &&
|
|
438
|
+
order.customer.isPremium &&
|
|
439
|
+
order.shippingMethod === 'express' &&
|
|
440
|
+
order.items.every(item => item.inStock)
|
|
441
|
+
) {
|
|
442
|
+
return 'ELIGIBLE_FOR_FREE_SHIPPING';
|
|
443
|
+
}
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
**After:**
|
|
447
|
+
```javascript
|
|
448
|
+
function isEligibleForFreeShipping(order) {
|
|
449
|
+
return (
|
|
450
|
+
isLargeOrder(order) &&
|
|
451
|
+
isPremiumCustomer(order) &&
|
|
452
|
+
isExpressShipping(order) &&
|
|
453
|
+
allItemsInStock(order)
|
|
454
|
+
);
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
function isLargeOrder(order) {
|
|
458
|
+
return order.total > 1000;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
function isPremiumCustomer(order) {
|
|
462
|
+
return order.customer.isPremium;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
function isExpressShipping(order) {
|
|
466
|
+
return order.shippingMethod === 'express';
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
function allItemsInStock(order) {
|
|
470
|
+
return order.items.every(item => item.inStock);
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
if (isEligibleForFreeShipping(order)) {
|
|
474
|
+
return 'ELIGIBLE_FOR_FREE_SHIPPING';
|
|
475
|
+
}
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
## Replace Loop with Pipeline
|
|
479
|
+
|
|
480
|
+
**Before:**
|
|
481
|
+
```javascript
|
|
482
|
+
function getTopExpensiveProducts(products) {
|
|
483
|
+
let inStock = [];
|
|
484
|
+
for (let product of products) {
|
|
485
|
+
if (product.inStock) {
|
|
486
|
+
inStock.push(product);
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
inStock.sort((a, b) => b.price - a.price);
|
|
491
|
+
|
|
492
|
+
let top5 = [];
|
|
493
|
+
for (let i = 0; i < 5 && i < inStock.length; i++) {
|
|
494
|
+
top5.push(inStock[i]);
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
let names = [];
|
|
498
|
+
for (let product of top5) {
|
|
499
|
+
names.push(product.name);
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
return names;
|
|
503
|
+
}
|
|
504
|
+
```
|
|
505
|
+
|
|
506
|
+
**After:**
|
|
507
|
+
```javascript
|
|
508
|
+
function getTopExpensiveProducts(products) {
|
|
509
|
+
return products
|
|
510
|
+
.filter(p => p.inStock)
|
|
511
|
+
.sort((a, b) => b.price - a.price)
|
|
512
|
+
.slice(0, 5)
|
|
513
|
+
.map(p => p.name);
|
|
514
|
+
}
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
## Remove Duplication
|
|
518
|
+
|
|
519
|
+
**Before:**
|
|
520
|
+
```javascript
|
|
521
|
+
function processOnlineOrder(order) {
|
|
522
|
+
validateOrder(order);
|
|
523
|
+
const total = calculateTotal(order);
|
|
524
|
+
const savedOrder = saveOrder(order, total);
|
|
525
|
+
sendEmail(order.customer.email, savedOrder.id);
|
|
526
|
+
logActivity('Order processed', savedOrder.id);
|
|
527
|
+
return savedOrder;
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
function processPhoneOrder(order) {
|
|
531
|
+
validateOrder(order);
|
|
532
|
+
const total = calculateTotal(order);
|
|
533
|
+
const savedOrder = saveOrder(order, total);
|
|
534
|
+
sendEmail(order.customer.email, savedOrder.id);
|
|
535
|
+
logActivity('Phone order processed', savedOrder.id);
|
|
536
|
+
return savedOrder;
|
|
537
|
+
}
|
|
538
|
+
```
|
|
539
|
+
|
|
540
|
+
**After:**
|
|
541
|
+
```javascript
|
|
542
|
+
function processOrder(order, source) {
|
|
543
|
+
validateOrder(order);
|
|
544
|
+
const total = calculateTotal(order);
|
|
545
|
+
const savedOrder = saveOrder(order, total);
|
|
546
|
+
sendEmail(order.customer.email, savedOrder.id);
|
|
547
|
+
logActivity(`${source} order processed`, savedOrder.id);
|
|
548
|
+
return savedOrder;
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
function processOnlineOrder(order) {
|
|
552
|
+
return processOrder(order, 'Online');
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
function processPhoneOrder(order) {
|
|
556
|
+
return processOrder(order, 'Phone');
|
|
557
|
+
}
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
## Refactoring Smells (When to Refactor)
|
|
561
|
+
|
|
562
|
+
### Long Method
|
|
563
|
+
**Smell:** Method has too many lines (>20-30)
|
|
564
|
+
**Refactor:** Extract Method
|
|
565
|
+
|
|
566
|
+
### Large Class
|
|
567
|
+
**Smell:** Class has too many responsibilities
|
|
568
|
+
**Refactor:** Extract Class
|
|
569
|
+
|
|
570
|
+
### Long Parameter List
|
|
571
|
+
**Smell:** Function has >3-4 parameters
|
|
572
|
+
**Refactor:** Introduce Parameter Object
|
|
573
|
+
|
|
574
|
+
### Duplicated Code
|
|
575
|
+
**Smell:** Same code in multiple places
|
|
576
|
+
**Refactor:** Extract Method/Class
|
|
577
|
+
|
|
578
|
+
### Dead Code
|
|
579
|
+
**Smell:** Unused code
|
|
580
|
+
**Refactor:** Delete it
|
|
581
|
+
|
|
582
|
+
### Comments Explaining What Code Does
|
|
583
|
+
**Smell:** Comment saying "This calculates discount"
|
|
584
|
+
**Refactor:** Extract method named `calculateDiscount()`
|
|
585
|
+
|
|
586
|
+
### Magic Numbers
|
|
587
|
+
**Smell:** Unexplained constants (42, 0.10, 1000)
|
|
588
|
+
**Refactor:** Named Constants
|
|
589
|
+
|
|
590
|
+
### Nested Conditionals
|
|
591
|
+
**Smell:** If inside if inside if
|
|
592
|
+
**Refactor:** Extract methods, early returns, guard clauses
|
|
593
|
+
|
|
594
|
+
## Safe Refactoring Workflow
|
|
595
|
+
|
|
596
|
+
### Step 1: Ensure Tests Pass
|
|
597
|
+
```bash
|
|
598
|
+
npm test
|
|
599
|
+
# All tests green ✅
|
|
600
|
+
```
|
|
601
|
+
|
|
602
|
+
### Step 2: Make Small Change
|
|
603
|
+
```javascript
|
|
604
|
+
// Extract one small method
|
|
605
|
+
function calculateSubtotal(items) {
|
|
606
|
+
return items.reduce((sum, item) =>
|
|
607
|
+
sum + item.price * item.quantity, 0
|
|
608
|
+
);
|
|
609
|
+
}
|
|
610
|
+
```
|
|
611
|
+
|
|
612
|
+
### Step 3: Run Tests Again
|
|
613
|
+
```bash
|
|
614
|
+
npm test
|
|
615
|
+
# Still green ✅
|
|
616
|
+
```
|
|
617
|
+
|
|
618
|
+
### Step 4: Commit
|
|
619
|
+
```bash
|
|
620
|
+
git add .
|
|
621
|
+
git commit -m "refactor: extract calculateSubtotal method"
|
|
622
|
+
```
|
|
623
|
+
|
|
624
|
+
### Step 5: Repeat
|
|
625
|
+
Next small refactoring...
|
|
626
|
+
|
|
627
|
+
## IDE Refactoring Tools
|
|
628
|
+
|
|
629
|
+
### Automated Refactorings (Safe)
|
|
630
|
+
- **Rename** - Change variable/function/class name everywhere
|
|
631
|
+
- **Extract Method** - Pull code into new function
|
|
632
|
+
- **Extract Variable** - Give expression a name
|
|
633
|
+
- **Inline** - Remove unnecessary abstraction
|
|
634
|
+
- **Move** - Relocate code to better place
|
|
635
|
+
|
|
636
|
+
### Use These!
|
|
637
|
+
Modern IDEs (VS Code, IntelliJ, WebStorm) do these safely with guaranteed correctness.
|
|
638
|
+
|
|
639
|
+
## Refactoring Anti-Patterns
|
|
640
|
+
|
|
641
|
+
### ❌ Refactoring Without Tests
|
|
642
|
+
**Problem:** No safety net, might break things
|
|
643
|
+
**Solution:** Write tests first, then refactor
|
|
644
|
+
|
|
645
|
+
### ❌ Big Bang Refactoring
|
|
646
|
+
**Problem:** Rewrite everything at once
|
|
647
|
+
**Solution:** Incremental refactoring, small steps
|
|
648
|
+
|
|
649
|
+
### ❌ Refactoring for Perfection
|
|
650
|
+
**Problem:** Endless tweaking
|
|
651
|
+
**Solution:** Good enough is good enough. Move on.
|
|
652
|
+
|
|
653
|
+
### ❌ Premature Abstraction
|
|
654
|
+
**Problem:** Creating abstractions before patterns clear
|
|
655
|
+
**Solution:** Wait for duplication, then extract
|
|
656
|
+
|
|
657
|
+
### ❌ Refactoring During Feature Work
|
|
658
|
+
**Problem:** Mixing refactoring with new features
|
|
659
|
+
**Solution:** Separate commits: refactor first, then feature
|
|
660
|
+
|
|
661
|
+
## Boy Scout Rule
|
|
662
|
+
|
|
663
|
+
**"Leave the code better than you found it."**
|
|
664
|
+
|
|
665
|
+
Every time you touch code:
|
|
666
|
+
1. Make it slightly better
|
|
667
|
+
2. Don't need to make it perfect
|
|
668
|
+
3. Small improvements accumulate
|
|
669
|
+
|
|
670
|
+
**Example:**
|
|
671
|
+
```javascript
|
|
672
|
+
// Found this
|
|
673
|
+
function calc(a,b,c){return a*b+c;}
|
|
674
|
+
|
|
675
|
+
// Left it as this
|
|
676
|
+
function calculateTotal(price, quantity, tax) {
|
|
677
|
+
return price * quantity + tax;
|
|
678
|
+
}
|
|
679
|
+
```
|
|
680
|
+
|
|
681
|
+
## Using with QE Agents
|
|
682
|
+
|
|
683
|
+
### Automated Refactoring Detection
|
|
684
|
+
|
|
685
|
+
**qe-quality-analyzer** identifies refactoring opportunities:
|
|
686
|
+
```typescript
|
|
687
|
+
// Agent detects code smells
|
|
688
|
+
const codeSmells = await agent.detectCodeSmells({
|
|
689
|
+
scope: 'src/services/',
|
|
690
|
+
patterns: [
|
|
691
|
+
'long-method',
|
|
692
|
+
'large-class',
|
|
693
|
+
'duplicate-code',
|
|
694
|
+
'feature-envy',
|
|
695
|
+
'data-clumps'
|
|
696
|
+
]
|
|
697
|
+
});
|
|
698
|
+
|
|
699
|
+
// Suggests specific refactorings
|
|
700
|
+
const suggestions = await agent.suggestRefactorings({
|
|
701
|
+
codeSmells,
|
|
702
|
+
preserveTests: true,
|
|
703
|
+
riskTolerance: 'low'
|
|
704
|
+
});
|
|
705
|
+
```
|
|
706
|
+
|
|
707
|
+
### Safe Refactoring with Test Verification
|
|
708
|
+
|
|
709
|
+
```typescript
|
|
710
|
+
// Agent validates refactoring didn't break behavior
|
|
711
|
+
const before = await git.getCurrentCommit();
|
|
712
|
+
await human.performRefactoring();
|
|
713
|
+
const after = await git.getCurrentCommit();
|
|
714
|
+
|
|
715
|
+
const validation = await qe-test-executor.verifyRefactoring({
|
|
716
|
+
beforeCommit: before,
|
|
717
|
+
afterCommit: after,
|
|
718
|
+
expectSameBehavior: true,
|
|
719
|
+
runFullSuite: true
|
|
720
|
+
});
|
|
721
|
+
|
|
722
|
+
// Returns: { testsPass: true, behaviorPreserved: true, coverageChange: +2% }
|
|
723
|
+
```
|
|
724
|
+
|
|
725
|
+
### Fleet Coordination for Large Refactorings
|
|
726
|
+
|
|
727
|
+
```typescript
|
|
728
|
+
// Multiple agents coordinate on large refactoring
|
|
729
|
+
const refactoringFleet = await FleetManager.coordinate({
|
|
730
|
+
strategy: 'refactoring',
|
|
731
|
+
agents: [
|
|
732
|
+
'qe-quality-analyzer', // Identify targets
|
|
733
|
+
'qe-test-generator', // Add safety tests
|
|
734
|
+
'qe-test-executor', // Verify behavior
|
|
735
|
+
'qe-coverage-analyzer' // Check coverage impact
|
|
736
|
+
],
|
|
737
|
+
topology: 'sequential'
|
|
738
|
+
});
|
|
739
|
+
|
|
740
|
+
await refactoringFleet.execute({
|
|
741
|
+
target: 'src/services/OrderService.ts',
|
|
742
|
+
refactoringType: 'extract-class'
|
|
743
|
+
});
|
|
744
|
+
```
|
|
745
|
+
|
|
746
|
+
---
|
|
747
|
+
|
|
748
|
+
## Related Skills
|
|
749
|
+
|
|
750
|
+
**Core Quality:**
|
|
751
|
+
- [agentic-quality-engineering](../agentic-quality-engineering/) - Agent-driven refactoring workflows
|
|
752
|
+
|
|
753
|
+
**Development:**
|
|
754
|
+
- [tdd-london-chicago](../tdd-london-chicago/) - Test coverage during refactoring
|
|
755
|
+
- [code-review-quality](../code-review-quality/) - Review refactored code
|
|
756
|
+
- [xp-practices](../xp-practices/) - Collective code ownership
|
|
757
|
+
|
|
758
|
+
**Testing:**
|
|
759
|
+
- [test-automation-strategy](../test-automation-strategy/) - Maintain test suite during refactoring
|
|
760
|
+
|
|
761
|
+
---
|
|
762
|
+
|
|
763
|
+
## Remember
|
|
764
|
+
|
|
765
|
+
Refactoring is not:
|
|
766
|
+
- Adding features
|
|
767
|
+
- Fixing bugs
|
|
768
|
+
- Optimizing performance
|
|
769
|
+
- Rewriting from scratch
|
|
770
|
+
|
|
771
|
+
Refactoring is:
|
|
772
|
+
- Improving code structure
|
|
773
|
+
- Making code easier to understand
|
|
774
|
+
- Reducing complexity
|
|
775
|
+
- Removing duplication
|
|
776
|
+
- **Without changing behavior**
|
|
777
|
+
|
|
778
|
+
**Always have tests. Always take small steps. Always keep tests green.**
|