Anti-Patterns and Pitfalls
Anti-patterns are recurring solutions to common problems that initially appear beneficial but ultimately lead to negative consequences. This section covers architectural, design, and organizational anti-patterns that cause systems to become hard to maintain, scale, and secure.
Key Anti-Patterns:
- Big Ball of Mud: Unstructured, difficult to navigate codebase
- Spaghetti Code: Complex control flow without clear structure
- God Object/Class: One component doing too much
- Golden Hammer: Using one solution for all problems
- Boat Anchor and Lava Flow: Obsolete code that won't go away
- Copy-Paste Programming: Violating DRY principle
- Premature Optimization: Optimizing before profiling
- Distributed Monolith: Microservices with monolithic coupling
- Chatty Interfaces: Excessive inter-component communication
- Over-Abstracting: Too many layers of indirection
- Anemic Domain Model: Domain objects without behavior
- Shared Database: Tight coupling via shared storage
- Overuse of Patterns: Patternitis
- Flaky Tests: Non-deterministic test failures
📄️ Big Ball of Mud
Comprehensive guide to Big Ball of Mud in software architecture
📄️ Spaghetti Code
Complex, tangled control flow without clear structure, making code hard to understand and modify.
📄️ God Object / God Class
One class doing too much with many responsibilities, violating single responsibility principle.
📄️ Golden Hammer
Using one familiar solution for every problem, even when better alternatives exist.
📄️ Boat Anchor and Lava Flow
Obsolete code that won't die, accumulating to form unmaintainable legacy.
📄️ Copy-Paste Programming
Duplicating code instead of extracting shared functionality, violating DRY principle.
📄️ Premature Optimization
Optimizing code before understanding where bottlenecks actually are.
📄️ Distributed Monolith
Microservices independent in deployment but tightly coupled in design.
📄️ Chatty Interfaces and Tight Coupling
Too much communication between objects, causing latency and tight coupling.
📄️ Over-Abstracting: Too Many Layers
Adding abstraction layers beyond what's needed, reducing clarity.
📄️ Anemic Domain Model
Domain objects that are just data containers, with business logic scattered elsewhere.
📄️ Shared Database Across Services
Multiple services accessing one shared database, creating tight coupling.
📄️ Overuse of Patterns: Patternitis
Using design patterns everywhere, even when simple solutions work better.
📄️ Flaky Tests and Non-Determinism
Tests that pass sometimes, fail other times due to timing, randomness, or shared state.