Skip to content

Software Design

Tier: 2 (Architectural Judgment)

Concepts: 14

Durability: Durable (Principles address essential complexity of managing change, coupling, and coherent behavior in software systems; concepts survived OOP, functional, and multi-paradigm transitions)


Fundamental Tensions

Tension Description
Flexibility vs. Simplicity Adding extension points increases future adaptability but introduces indirection and cognitive load. Cannot be eliminated because future requirements are unknown, yet every abstraction has a comprehension cost.
Abstraction vs. Indirection Deep abstractions hide complexity but add layers that obscure understanding and debugging. The tension exists because abstraction requires indirection, yet too many layers create "lasagna code" as harmful as "spaghetti code."
YAGNI vs. Extensibility Building for future needs risks over-engineering, but not building for them risks costly rewrites. Cannot be resolved because predicting which extensions will be needed requires knowledge we fundamentally lack at design time.
Inheritance vs. Composition Inheritance enables code reuse through hierarchy but creates rigid coupling; composition enables flexibility but requires more explicit wiring. The tension persists because both are valid mechanisms with different cost profiles depending on domain stability.
Fail-Fast vs. Fault Tolerance Detecting errors immediately aids debugging but may cause cascading failures; tolerating errors enables resilience but may hide bugs. Cannot be eliminated because error handling strategy depends on context and consequences that vary across system layers.

Concepts


Cross-Domain Transfer Summary

This Domain Concept Transfers To
Single Responsibility Software Architecture, API Design, Database Design
Open/Closed Software Architecture, API Design, Testing Strategies
Liskov Substitution Type Systems, API Design, Testing Strategies
Interface Segregation API Design, Microservices, Testing Strategies
Dependency Inversion Software Architecture, Testing Strategies, Plugin Systems
Composition Over Inheritance Functional Programming, UI Frameworks, Microservices
Information Hiding Software Architecture, API Design, Database Design
Deep vs. Shallow Modules API Design, Library Design, Abstraction Layers
Design Patterns Architecture Patterns, Integration Patterns, Concurrency Patterns
Law of Demeter API Design, Microservices, Data Access
Command-Query Separation CQRS Architecture, Functional Programming, API Design
State Machines Protocol Design, Workflow Systems, UI State, Compilers
Fail-Fast Distributed Systems, API Design, Testing, Databases
Dependency Injection Testing Strategies, Software Architecture, Functional Programming


Canonical Sources

Source Coverage
Gamma, Helm, Johnson, Vlissides, "Design Patterns" (1994) Design patterns, composition over inheritance, foundational OO design
Martin, "Agile Software Development, Principles, Patterns, and Practices" (2002) SOLID principles comprehensive treatment
Ousterhout, "A Philosophy of Software Design" (2018) Deep vs. shallow modules, complexity management, modern design philosophy
Meyer, "Object-Oriented Software Construction" (1988, 1997) Open/Closed principle, Design by Contract, Command-Query Separation
Parnas, "On the Criteria To Be Used in Decomposing Systems into Modules" (1972) Information hiding, module decomposition criteria
Liskov & Wing, "A Behavioral Notion of Subtyping" (1994) Formal treatment of substitutability
Hunt & Thomas, "The Pragmatic Programmer" (1999, 2019) Practical design principles, fail-fast, DRY
Fowler, "Patterns of Enterprise Application Architecture" (2002) Enterprise patterns, dependency injection concepts
Bloch, "Effective Java" (2001, 2008, 2017) Composition over inheritance, practical design guidance
Constantine & Yourdon, "Structured Design" (1979) Coupling and cohesion foundations