|
| 1 | +--- |
| 2 | +alias: AHA Principle, Avoiding Hasty Abstractions, Moist Programming |
| 3 | +category: General |
| 4 | + |
| 5 | +publish: true |
| 6 | +slug: avoid-hasty-abstractions-aha |
| 7 | + |
| 8 | +title: Avoid Hasty Abstractions (AHA) |
| 9 | +summary: Prefer duplication over the wrong abstraction. Avoid rushing into creating abstractions without a clear understanding of the problem domain. |
| 10 | +draft: false |
| 11 | +tags: ['Code Tips'] |
| 12 | +date: 2023-06-23 |
| 13 | +--- |
| 14 | + |
| 15 | +## Usage |
| 16 | + |
| 17 | +### 📝 Guideline |
| 18 | + |
| 19 | +**Avoid Hasty Abstractions**: Prefer duplication over the wrong abstraction. |
| 20 | + |
| 21 | +Avoid rushing into creating abstractions without a clear understanding of the problem domain. It is better to tolerate duplication initially than to create premature or incorrect abstractions. |
| 22 | + |
| 23 | +### 🛠️ How to Apply |
| 24 | + |
| 25 | +- **Prefer duplication**: If you're unsure about the correct abstraction, it's better to have duplicated code temporarily until you fully understand the commonalities and requirements for abstraction. 📊 |
| 26 | +- **Identify commonalities**: Look for patterns and similarities in the duplicated code. When you notice parts that can be generalized, you'll be in a better position to provide meaningful abstractions. 🧩 |
| 27 | +- **Consider future requirements**: Instead of prematurely optimizing for performance or designing the "perfect" API, focus on code that can easily adapt to future changes. 🔮 |
| 28 | +- **Avoid premature abstractions**: If you abstract too early, you might end up with complex code that's difficult to maintain. Wait until you have a good understanding of the use cases before creating abstractions. 🚧 |
| 29 | +- **Mindful Abstraction**: When the commonalities are clear, it's the right time to create abstractions. Abstract out the shared functionality into functions or modules that accurately capture the essence of the problem. 🌤️ |
| 30 | + |
| 31 | +## Pros and Cons |
| 32 | + |
| 33 | +### 👍 Pros |
| 34 | + |
| 35 | +- **Increased Clarity**: Duplicating code initially allows you to gain a deeper understanding of the problem, leading to clearer and more concise abstractions. 🔍 |
| 36 | +- **Flexible Adaptation**: Delaying abstractions until commonalities are well-understood enables easier adaptation to future changes in requirements or use cases. 🔄 |
| 37 | +- **Accurate abstractions**: By avoiding hasty abstractions, you ensure that your abstractions accurately represent the underlying problem domain. 🎯 |
| 38 | + |
| 39 | +### 👎 Cons |
| 40 | + |
| 41 | +- **Code duplication**: Delaying abstractions may result in some code duplication, which can be seen as a drawback.♻️ |
| 42 | +- **Maintenance overhead**: Duplicated code may require updates in multiple places if changes are needed, leading to increased maintenance overhead. 🪨 |
| 43 | + |
| 44 | +## Examples |
| 45 | + |
| 46 | +### ❌ Bad |
| 47 | + |
| 48 | +```typescript |
| 49 | +// Bad Example: Hasty Abstraction that don't provide much value and forces one item per operation |
| 50 | +function performOperation(items: Item[], operation: string): void { |
| 51 | + for (const item of items) { |
| 52 | + performCustomOperation(item, operation) |
| 53 | + } |
| 54 | +} |
| 55 | + |
| 56 | +function performCustomOperation(item: Item, operation: string): void { |
| 57 | + if (operation === 'operation1') { |
| 58 | + // Custom operation 1 |
| 59 | + } else if (operation === 'operation2') { |
| 60 | + // Custom operation 2 |
| 61 | + } |
| 62 | + // More operations... |
| 63 | +} |
| 64 | +``` |
| 65 | + |
| 66 | +### ✅ Good |
| 67 | + |
| 68 | +```typescript |
| 69 | +// Good Example: Avoid Hasty Abstraction |
| 70 | + |
| 71 | +function performOperation(items: Item[], operation: string): void { |
| 72 | + if (operation === 'operation1') { |
| 73 | + for (const item of items) { |
| 74 | + // Custom operation 1 logic |
| 75 | + } |
| 76 | + } else if (operation === 'operation2') { |
| 77 | + for (const item of items) { |
| 78 | + // Custom operation 2 logic |
| 79 | + } |
| 80 | + } |
| 81 | + // More operations... |
| 82 | +} |
| 83 | +``` |
| 84 | + |
| 85 | +## References |
| 86 | + |
| 87 | +### 🔀 Related principles |
| 88 | + |
| 89 | +- **Optimize for change first**: This principle complements AHA by emphasizing the need for flexibility in the face of evolving requirements. 🔧 |
| 90 | +- [**Don't Repeat Yourself (DRY)**](/blog/dont-repeat-yourself-dry): While AHA suggests temporary duplication, DRY focuses on removing duplication through well-designed abstractions. 🔄 |
| 91 | +- [**Write Everything Twice (WET)**](/blog/write-everything-twice-wet): AHA encourages careful consideration of abstractions, which aligns with the idea of avoiding unnecessary complexity promoted by WET. ♻️ |
0 commit comments