// SOLID & Principles · 08
YAGNI
You Aren't Gonna Need It: build for today's requirements only.
How it fits together
- ReportPage uses / calls ExportService (Export(report))
- ExportService uses / calls ExportTarget (via interface)
- CsvExporter implements ExportTarget
- PdfExporter implements ExportTarget
- ReportPage uses / calls ExportService (Export(report))
- ExportService creates CsvExporter (new per call)
Spot it
- Config flags nobody has ever changed
- Abstractions built for imagined customers
- Code paths with no caller and no test
It costs
Ignoring known, near-term needs can force costly rework, especially in data and public APIs.
In code
public sealed class CsvExporter{ public void Write(Report report, Stream stream) { using var writer = new StreamWriter(stream, leaveOpen: true); foreach (var row in report.Rows) { writer.WriteLine(string.Join(',', row)); } }}public sealed class ExportService{ public byte[] Export(Report report) { var exporter = new CsvExporter(); using var stream = new MemoryStream(); exporter.Write(report, stream); return stream.ToArray(); }}Go deeperThe full explanation and what to ask for · 1 min readExpandCollapse
From Extreme Programming: implement things when you actually need them, never when you only foresee that you might.
It is not an excuse for poor design. YAGNI assumes the code stays easy to change, which is why it pairs with tests and refactoring; without them, deferring just piles up debt.
It applies to features, not to cheap, reversible care. Public API contracts, data schemas and security are expensive to change later, so think ahead there.
Ask for it
- speculative generality
- presumptive feature
- cost of carry
- last responsible moment
- refactoring
Review this branch for speculative generality: options, extension points and abstractions that no current requirement uses. List each with what it costs to keep, and remove the ones we could add back later in under a day.