If you know a software architect, a professor who teaches SOLID or packaging principles, or anyone who takes design principles seriously — I'd appreciate you sharing this with them. The argument needs to be challenged by practitioners and researchers alike.
A companion paper showed that ISP is a corollary of DIP at the class level. That settles which elements exist. It doesn't settle where they live in the package structure.
The paper I'm announcing here asks that question — and provides a formal proof that Martin's packaging principles cannot be applied simultaneously in general, and are in fact contradictory for a common class of dependency configurations.
The setup
Five elements: a provider A implementing two client-specific interfaces I_B and I_C, and two clients B and C depending on their respective interfaces. This is the minimal non-trivial DIP/ISP-compliant configuration — and a routine dependency pattern in object-oriented software.
52 ways to partition five elements into packages. Martin gives us eight principles (DIP, ISP, and six packaging principles: REP, CCP, CRP, ADP, SDP, SAP) to narrow the space.
The result
CCP and REP are jointly unsatisfiable.
CCP says: elements that change for the same reasons belong in the same package. Under DIP's ownership clause, I_B changes for the same reasons as B. So CCP puts I_B with B.
REP says: every package must be a viable unit of reuse — no consumer should be forced to accept elements it doesn't use. A must implement I_B, so A's package must depend on whichever package contains I_B. If I_B is packaged with B (as CCP requires), A is forced to take a dependency on B even though it never uses B. REP is violated.
No partition satisfies both. The proof is two steps, and it generalizes to any system where a provider serves two or more clients through client-specific interfaces.
It gets worse
Martin presents CCP, CRP, and REP as a "tension triangle" — three principles pulling in different directions, with the architect choosing which vertex to sacrifice. This sounds like a navigable trade-off space. It isn't.
Dropping REP from the triangle still yields zero satisfying partitions: CCP and CRP together remain unsatisfiable for the same configuration. Dropping CRP fares no better — the CCP/REP conflict that started this analysis is still there, unresolved. Only dropping CCP produces any solutions at all, and even then five partitions survive with no principle left to select among them. Two of the three escape hatches lead nowhere. The triangle has no navigable interior.
Adding DIP back into the picture doesn't rescue things. The co-location reading contradicts REP; the examples reading contradicts ISP; and the ownership reading adds no packaging constraint at all. The only DIP interpretation that doesn't eliminate the five surviving partitions is the one that stays silent on where packages should go.
Every recommendation is self-defeating
The three natural placements — with client, with provider, own package — each have principled support and principled condemnation from within the same framework. The principles don't just fail to agree on a winner; they actively indict every candidate they put forward.
Why this matters
If no packaging satisfies all principles, then any system containing a multi-client provider configuration violates at least one principle at every point in its history. The concept of "technical debt" implies a principled ideal to return to. For packaging, no such ideal exists.
Students who learn SOLID and the packaging principles as a coherent methodology will attempt to satisfy all of them, fail, and draw one of two wrong conclusions: (a) "I'm not skilled enough yet," or (b) "principles are just guidelines." Neither is correct. The correct conclusion — that these specific principles are collectively unsatisfiable — has not been available because the unsatisfiability was never demonstrated.
The paper
"SOLID: Where Do Client-Owned Interfaces Live? DIP, ISP, and the Packaging Principles"
Can you find a packaging of any multi-client provider configuration that satisfies CCP and REP simultaneously? If you think the formalization is too strict — that CCP should be a preference rather than a constraint — what does it mean to call something a "principle" if it can always be overridden by judgment?
Top comments (0)