Why Do We Need SOLID Principles at All?
SOLID principles are not laws of physics, but a set of empirical rules aimed at combating software entropy.
Deep Dive (Under the Hood)
SOLID principles are not laws of physics, but a set of empirical rules aimed at combating software entropy.
In 2000, Robert Martin described “signs of rotting design” that SOLID is designed to eliminate:
- Rigidity: The system resists changes. One small change requires editing many other modules.
- Fragility: A change in one place breaks code in completely unrelated places.
- Immobility: It’s impossible to reuse part of the code in another system, as it’s firmly glued to the current context.
- Viscosity — when it’s easier for a developer to make a “hack” or “workaround” than to follow the architectural style. Example: to add a field, you need to change 5 interfaces and 10 classes (high viscosity). Or simply add one field (low viscosity).
Senior Insight: SOLID as an Economic Tool
At the Senior level, it’s important to understand that SOLID costs money. Creating abstractions, interfaces, and splitting classes takes more time during development.
- Why pay? To reduce Total Cost of Ownership (TCO).
- When does it pay off? On long-lived projects (> 6 months), where maintenance cost far exceeds the cost of writing code.
SOLID in Distributed Systems (Microservices)
SOLID principles scale from the class level to the service level:
- SRP -> A microservice should be responsible for one business function.
- OCP -> A service should be extended through new endpoints or events, without breaking the old API.
- LSP -> Different implementations of the same service (e.g., different versions) must comply with the API contract.
- ISP -> Clients should not depend on JSON fields they don’t read (using GraphQL or Consumer Driven Contracts).
- DIP -> Services should depend on stable API/Contracts, not on implementation details of other services.
Dangers and Extremes
When to consciously violate SOLID:
- 50-line script — SRP/OCP are excessive
- One-time data migration — DI/DIP is not needed
- Production hotfix — fix first, refactor later
- YAGNI (You Ain’t Gonna Need It): Often developers build “airfields” of interfaces where one method would suffice. This creates “complexity for complexity’s sake”.
- KISS (Keep It Simple, Stupid): Sometimes violating SOLID (e.g., a small switch) makes code clearer than 10 strategy classes.
Diagnostics and Metrics
There are formal code quality metrics based on SOLID:
- LCOM (Lack of Cohesion in Methods): Measures how closely class methods are related. High LCOM = SRP violation.
- Afferent/Efferent Coupling: Measures incoming and outgoing dependencies of a module. Balance of these metrics indicates correct DIP.
- Maintainability Index: Integral indicator in tools like SonarQube.
Code metrics:
- LCOM > 0.8 = cohesion problems (class methods are not related to each other)
- Afferent Coupling = how many modules depend on this module (incoming dependencies)
- Efferent Coupling = how many modules this module depends on (outgoing dependencies)
- Balance: stable modules have high Afferent, low Efferent
Summary for Senior
- SOLID reduces the frequency of cascading edits when adding new functionality, but doesn’t protect against changes in the domain model itself.
- Use SOLID only where changes are expected.
- Principles help make code testable (through DI and mocks).
- Don’t turn SOLID into a cult; common sense and simple solutions (KISS) always take priority.
🎯 Interview Cheat Sheet
Must know:
- SOLID fights 4 signs of rotting design: Rigidity, Fragility, Immobility, Viscosity
- SOLID is an economic tool: reduces Total Cost of Ownership on long-lived projects (>6 months)
- Principles scale to microservices (SRP → one service = one business function)
- LCOM measures cohesion, Afferent/Efferent Coupling — dependency balance
- Conscious SOLID violation: scripts, one-time data migrations, production hotfixes
- YAGNI and KISS — counterbalances to over-engineering through SOLID
Common follow-up questions:
- What is Viscosity? — When it’s easier for a developer to make a “workaround” than follow the architecture
- When does SOLID not pay off? — Prototypes, scripts up to 50 lines, one-time data migrations
- How does SOLID affect microservices? — SRP → one service = one function, LSP → versions comply with API contract
- What does LCOM > 0.8 mean? — Cohesion problems: class methods are not related to each other
Red flags (DO NOT say):
- “SOLID are laws, they cannot be violated” (they are empirical rules, there are justified exceptions)
- “SOLID makes code perfect” (can lead to over-engineering and complexity for complexity’s sake)
- “Need to apply SOLID to all code” (YAGNI: only where changes are expected)
Related topics:
- [[20. Is it possible to follow all SOLID principles simultaneously]]
- [[19. How SOLID principles help when extending functionality]]
- [[15. How SOLID helps in code testing]]
- [[22. Which anti-patterns contradict SOLID principles]]