← CodeClarityLab Home
Browse by Category
+ added · updated 7d
← Back to glossary

Speculative Generality

quality Intermediate

Also Known As

over-engineering YAGNI violation future-proofing smell

TL;DR

Unused abstractions, parameters, or hooks added for hypothetical future use that complicate the codebase without present value.

Explanation

Speculative generality is the code smell version of over-engineering: creating abstract classes with one subclass, adding unused parameters for flexibility, or writing hook points for requirements that don't exist yet. It violates YAGNI and adds cognitive overhead for every reader. Remove unused abstractions, parameters, and delegate methods that serve no current purpose — refactoring tools make re-introducing them straightforward if the need genuinely arises.

Common Misconception

Adding flexibility upfront saves refactoring time later. Speculative abstractions are rarely used as anticipated, add cognitive load now, and often need to be redesigned anyway when real requirements arrive — YAGNI exists because the cost of speculative code is immediate and certain.

Why It Matters

Code written for imagined future requirements adds complexity now for no current value — if the requirement never materialises, the abstraction is dead weight that obstructs simpler solutions.

Common Mistakes

  • Adding abstract base classes 'in case we need another implementation later' with only one concrete class.
  • Plugin architectures for internal code that never needs to be pluggable.
  • Configuration files for behaviour that has never varied and shows no sign of varying.
  • Not applying YAGNI — the cost of adding abstraction when needed is almost always less than carrying premature abstraction.

Code Examples

💡 Note
Speculative abstractions add complexity now for benefits that may never arrive. Refactor when the second real case exists.
✗ Vulnerable
// Built for flexibility nobody asked for yet
interface AbstractDataProviderFactoryInterface {
    public function create(string \$type): DataProviderInterface;
}
class ConcreteDataProviderFactory implements AbstractDataProviderFactoryInterface {
    public function create(string \$type): DataProviderInterface {
        return new DatabaseDataProvider(); // only one type ever exists
    }
}
✓ Fixed
// YAGNI — build what's needed today
class DatabaseDataProvider {
    public function getData(): array { return \$this->db->fetchAll(); }
}
// Add the interface/factory if and when a second provider materialises

Added 15 Mar 2026
Edited 28 Apr 2026
Views 26
AI edit PF Media Bot Claude Opus 4.5 on refs · 28 Apr 2026
Edits history 1 edit
  1. refs PF Media Bot Claude Opus 4.5 · 28 Apr 2026
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
1 ping F 0 pings S 1 ping S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 1 ping S 2 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 2 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 1 ping S 1 ping S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S
No pings yet today
No pings yesterday
Amazonbot 7 Perplexity 3 Google 2 Unknown AI 2 SEMrush 2 Ahrefs 1
crawler 16 crawler_json 1
DEV INTEL Tools & Severity
🟡 Medium ⚙ Fix effort: Medium
⚡ Quick Fix
Delete the abstract base class with one concrete implementation, the plugin system with zero plugins, and the configuration option nobody uses — remove code for future requirements that may never come
📦 Applies To
any web cli queue-worker
🔗 Prerequisites
🔍 Detection Hints
Abstract class with single implementation; interface only ever implemented once; method parameter never used by any caller; over-engineered config system
Auto-detectable: ✓ Yes phpstan phpmd php-dead-code
⚠ Related Problems
🤖 AI Agent
Confidence: Medium False Positives: Medium ✓ Auto-fixable Fix: Medium Context: Class Tests: Update

✓ schema.org compliant