1.3 SOLID, DRY, and the failure of DDD
When good principles become mandatory abstraction layers.
SOLID, DRY, and the failure of DDD
SOLID and DRY are fine. They became a problem when the industry turned them into religion and DDD into mandatory theatre.

SOLID — principles, not a building code
Section titled “SOLID — principles, not a building code”- Single responsibility: good until every class is one line and your navigation is a war crime.
- Open/closed: good until you wrap everything in inheritance because “extension points.”
- Liskov: good until nobody can explain why your “rectangle” broke the square.
- Interface segregation: good until you have seventeen
IThingReadervariants for one CSV import. - Dependency inversion: good until it means a DI container black box that injects everything because it can.

Beskid’s compiler-side take (see also the compiler README): IoC is a direction; IoC frameworks are not. Inversion of control belongs in compile-time wiring you can verify, not in runtime indirection you discover when production logs start speaking in interfaces.
DRY — do not repeat yourself (into a monolith)
Section titled “DRY — do not repeat yourself (into a monolith)”DRY was never “one copy of every string in the universe.” It was one authoritative place for each rule.
What happened in the wild:
- Shared “utility” assemblies that couple every service to every other service’s mistakes.
- Generic repositories because someone heard DRY and panicked.
- Abstractions that exist only so two teams do not talk to each other.

Sometimes repetition is cheaper than the wrong abstraction. Beskid prefers compile-time reuse (modules, metaprogramming) over runtime cleverness (reflection, service locator soup).
DDD — domain-driven déjà vu
Section titled “DDD — domain-driven déjà vu”Domain-Driven Design contains useful ideas: ubiquitous language, bounded contexts, explicit boundaries. The industry implementation is often:
- Draw aggregates on a whiteboard.
- Invent seventeen entity types for a table with four columns.
- Add “domain services” because the entity got fat.
- Add “application services” because the domain service got fat.
- Add “infrastructure” folders until the repo looks like a matryoshka doll of interfaces.
- Ship the same CRUD anyway, but now onboarding takes a quarter.
DDD forces overcomplication when:
- The business is mostly state transitions on rows (it usually is).
- The team treats patterns as moral requirements, not tools.
- “Rich domain models” become anemic data with aggressive naming.
The failure mode is not DDD the book—it is DDD the performance: architects performing complexity so stakeholders feel sophistication.

What Beskid does instead (preview)
Section titled “What Beskid does instead (preview)”- Language features are language features—not ten layers of corelib and framework glue.
- Prefer explicit modules and compile-time composition over runtime discovery.
- Make illegal states harder at compile time without inventing a new bounded context for
EmailAddress.