Mmcp.market

software-design-philosophy skill

by wondelai·wondelai/skills·2.3k stars·MIT

Manage software complexity through deep modules, information hiding, and strategic programming. Use when the user mentions "module design", "API too complex", "shallow class", "complexity budget", "strategic vs tactical", "deep module", "information leakage", "pass-through method", "this code is over-engineered", or "simplify this design". Also trigger when reviewing an interface for simplicity, evaluating whether an abstraction is pulling its weight, deciding whether a comment is worth writing, or choosing between general-purpose and special-purpose approaches. Covers deep vs shallow modules, red flags for complexity, and comments as design documentation. For code quality, see clean-code. For architecture boundaries, see clean-architecture.

A100/100content scan

Is the software-design-philosophy skill safe?

Clean: nothing in its files matched our rules. We read 7 files in the folder on 2026-09-28.

No findings.

Install the software-design-philosophy skill

A skill is a folder. Copy it into your agent's skills folder and the agent loads it when the task matches its description.

git clone --depth 1 https://github.com/wondelai/skills.git /tmp/skills
mkdir -p ~/.claude/skills
cp -r /tmp/skills/plugins/code-craftsmanship/skills/software-design-philosophy ~/.claude/skills/software-design-philosophy
available in every project

In the Claude apps, zip the folder and upload it from the Skills settings. The folder on GitHub

The instructions your agent would load

SKILL.md as published, without the frontmatter. Read it on GitHub

A Philosophy of Software Design Framework

A practical framework for managing the fundamental challenge of software engineering: complexity. Apply these principles when designing modules, reviewing APIs, refactoring code, or advising on architecture decisions.

Core Principle

The greatest limitation in writing software is our ability to understand the systems we are creating. Complexity is the enemy: it makes systems hard to understand, hard to modify, and a source of bugs. Evaluate every design decision by asking "Does this increase or decrease the overall complexity of the system?" — the goal is not zero complexity, but minimizing unnecessary complexity and concentrating the necessary kind where it can be managed.

Scoring

Goal: 10/10. When reviewing or creating a design, score it by counting how many of the eight Quick Diagnostic rows it satisfies (≈1.25 points each), then sanity-check against the bands:

  • 9-10 — deep modules with interfaces far simpler than implementations; no information leakage (an implementation can change without touching callers); interface comments capture design intent; design improvement is routine. All eight diagnostics pass.
  • 6-8 — mostly deep, but one or two leaks, shallow classes, or undocumented abstractions. 5-6 diagnostics pass.
  • 3-5 — classitis or temporal decomposition, recurring leakage, comments that only restate code. 2-4 diagnostics pass.
  • ≤2 — tactical-tornado code: shallow modules, pervasive leakage, no design intent recorded. 0-1 diagnostics pass.

Always state the current score, the diagnostic rows that failed, and the specific change each one needs to reach 10/10.

The Software Design Framework

Six principles for managing complexity and producing systems that are easy to understand and modify:

1. Complexity and Its Causes

Core concept: Complexity is anything about a system's structure that makes it hard to understand and modify. It shows three symptoms — change amplification, cognitive load, and unknown unknowns — and has two causes: dependencies and obscurity.

Key insights:

  • Change amplification: a simple change requires edits in many places
  • Cognitive load: a developer must hold too much in mind to make a change
  • Unknown unknowns: it isn't obvious what must change or what information is relevant — the worst symptom
  • Complexity is incremental — it accumulates from hundreds of small decisions ("death by a thousand cuts"), so every decision matters

Code applications:

See references/complexity-symptoms.md when you need to name which symptom a codebase has before fixing it — per-symptom recognition tests, the dependency taxonomy (syntactic/semantic/temporal/hidden), the C = Σ(cp·tp) cost formula, and a 10-row red-flag table.

2. Deep vs Shallow Modules

Core concept: The best modules are deep: powerful functionality behind a simple interface. Shallow modules have complex interfaces relative to the functionality they provide — they add complexity rather than hiding it.

Why it works: The interface is the cost a module imposes on the rest of the system; the implementation is the benefit. So a method that is harder to learn than to re-implement yourself is net-negative — depth, not line count, decides whether a module earns its place.

Key insights:

  • Depth = functionality provided / interface complexity imposed (Unix file I/O is deep; thin Java I/O wrappers are shallow)
  • "Classitis": the disease of creating too many small, shallow classes — each interface adds cognitive load
  • Small methods are not inherently good; depth matters more than size
  • The best abstractions hide significant complexity behind a few simple concepts

Code applications:

See references/deep-modules.md when judging whether an abstraction pulls its weight — before/after code for the depth ratio, the classitis cure worked out, and case studies (Unix I/O, GC, TCP/IP).

3. Information Hiding and Leakage

Core concept: Each module should encapsulate knowledge not needed by other modules. Information leakage — one design decision reflected in multiple modules — is one of the most important red flags in software design.

Why it works: A decision that lives in one module can change there and nowhere else; the same decision leaked into N modules turns one edit into N edits that no compiler will remind you to make. Hiding is what converts change amplification back into a local change.

Key insights:

  • Temporal decomposition causes leakage: splitting code by when things happen forces shared knowledge across phases — organize by knowledge instead
  • Back-door leakage through data formats, protocols, or shared assumptions is the subtlest form
  • Decorators frequently leak — they expose the decorated interface
  • If two modules share knowledge, merge them or create a new module that encapsulates it

Code applications:

See references/information-hiding.md when a change forces you to edit two modules in lockstep — the four leakage forms with code (interface, back-door, temporal, decorator), five reduction strategies, the HTTP-handling case study, and a detection table.

4. General-Purpose vs Special-Purpose Modules

Core concept: Design modules that are "somewhat general-purpose": an interface general enough to support multiple uses, with an implementation that handles current needs. Ask: "What is the simplest interface that will cover all my current needs?"

Why it works: Counterintuitively, the general interface is usually the simpler one — special-case methods multiply as requirements grow, while one general method absorbs them. The trap is the other direction: generality the current needs don't demand is speculative complexity, paid now for a use case that may never arrive.

Key insights:

  • "Somewhat general-purpose" is the sweet spot between too specific and too generic
  • Push complexity downward: lower-level modules should handle hard cases so upper levels stay simple
  • Configuration parameters often represent a failure to decide — each parameter is complexity pushed onto the caller
  • When in doubt, implement the simpler, more general-purpose approach first

Code applications:

See references/general-vs-special.md when choosing how general an interface should be — the "simplest interface for all current needs" test, the configuration-parameter antipattern, and push-complexity-downward worked through.

5. Comments as Design Documentation

Core concept: Comments should describe what is not obvious from the code: design intent, abstraction rationale, invariants, and assumptions. "Good code is self-documenting" is a myth for anything beyond low-level implementation detail.

Why it works: Code can only ever record what it does — never why this approach over the alternatives, or what it silently assumes. That rationale is the most perishable information in a system: it lives only in the author's head and is gone the moment they move on, so a comment is the single chance to capture it.

Key insights:

  • Four types: interface comments (most important — they define the abstraction), data structure member comments, implementation comments, cross-module comments
  • Write comments first (comment-driven design) to clarify thinking before code
  • Don't repeat what the code makes clear; keep comments next to the code they describe and update them together
  • If a comment is hard to write, the design may be too complex

Code applications:

See references/comments-as-design.md when writing or reviewing comments and unsure what belongs in one — the four comment types with examples, the comment-driven-design procedure, and the rebuttal to the self-documenting-code myth.

6. Strategic vs Tactical Programming

Core concept: Tactical programming gets features working quickly and accumulates complexity with each shortcut. Strategic programming invests 10-20% extra effort in good design, treating every change as an opportunity to improve structure.

Why it works: Tactical speed is borrowed: each shortcut makes future changes harder, while the strategic investment compounds — strategically designed systems are faster to work with within months.

Key insights:

  • Tactical tornado: a developer who ships fast but leaves wreckage — celebrated short-term, destructive long-term
  • Your primary job is a great design that happens to work, not working code that happens to have a design
  • Startups need strategic programming most — early shortcuts compound into crippling debt as the team grows
  • Every change is an investment opportunity: leave the code a little better; refactoring is part of every feature, not a special event

Code applications:

See references/strategic-programming.md when deciding how much design effort a change deserves, or making the case for it — the 10-20% investment math, the tactical-tornado pattern, and why startups need strategic programming most.

Common Mistakes

Quick Diagnostic

Further Reading

For the complete methodology with detailed examples:

  • "A Philosophy of Software Design" by John Ousterhout (2nd edition)

About the Author

John Ousterhout is the Bosack Lerner Professor of Computer Science at Stanford and the creator of the Tcl scripting language and Tk toolkit. He developed A Philosophy of Software Design from his Stanford CS 190 course, distilling decades of systems-building experience into principles that apply across languages and scales.

More skills from wondelai/skills

  • A37signals-wayBuild lean, opinionated products using the 37signals philosophy from "Getting Real", "Rework", and "Shape Up". Use when the user mentions "Getting Real", "Rework", "Shape Up", "37signals", "Basecamp method", "six-week cycles", "fixed time variable scope", "appetite vs estimates", "betting table", "breadboarding", "fat marker sketch", "build less", "underdo the competition", "opinionated software", "we have too many meetings", "how do we ship faster", or "stop overbuilding". Also trigger when cutting scope to ship sooner, running a small team, or avoiding long-term roadmaps. Covers shaping, betting, building, and the art of saying no. For MVP validation, see lean-startup. For design sprints, see design-sprint.
  • A37signals-wayBuild lean, opinionated products using the 37signals philosophy from "Getting Real", "Rework", and "Shape Up". Use when the user mentions "Getting Real", "Rework", "Shape Up", "37signals", "Basecamp method", "six-week cycles", "fixed time variable scope", "appetite vs estimates", "betting table", "breadboarding", "fat marker sketch", "build less", "underdo the competition", "opinionated software", "we have too many meetings", "how do we ship faster", or "stop overbuilding". Also trigger when cutting scope to ship sooner, running a small team, or avoiding long-term roadmaps. Covers shaping, betting, building, and the art of saying no. For MVP validation, see lean-startup. For design sprints, see design-sprint.
  • A37signals-wayBuild lean, opinionated products using the 37signals philosophy from "Getting Real", "Rework", and "Shape Up". Use when the user mentions "Getting Real", "Rework", "Shape Up", "37signals", "Basecamp method", "six-week cycles", "fixed time variable scope", "appetite vs estimates", "betting table", "breadboarding", "fat marker sketch", "build less", "underdo the competition", "opinionated software", "we have too many meetings", "how do we ship faster", or "stop overbuilding". Also trigger when cutting scope to ship sooner, running a small team, or avoiding long-term roadmaps. Covers shaping, betting, building, and the art of saying no. For MVP validation, see lean-startup. For design sprints, see design-sprint.
  • Aarchitecture-optimizationGuided journey from a working codebase grown slow and tangled to one measurably fast, cleanly bounded, and readable. Orchestrates eight skills phase by phase - working-with-legacy-code, clean-architecture, software-design-philosophy, refactoring-patterns, system-design, ddia-systems, release-it, pragmatic-programmer - every phase carries its method inline so it runs standalone, asking the user questions at every decision point and recording results in the project docs/ folder (PERFORMANCE.md, ARCHITECTURE.md, ARCHITECTURE-OPTIMIZATION-PLAN.md) so the journey resumes across sessions. Use when the user wants to make an app faster, untangle drifted boundaries, fix slow endpoints and queries, or says ''it works but it is slow and getting worse''. For an untested prototype, improve-code-quality; for an aged codebase you fear to touch, remove-technical-debt; for greenfield structure, design-code-architecture; for marketing-site page speed, improve-website. For one framework in isolation, invoke that skill directly.
  • Aarchitecture-optimizationGuided journey from a working codebase grown slow and tangled to one measurably fast, cleanly bounded, and readable. Orchestrates eight skills phase by phase - working-with-legacy-code, clean-architecture, software-design-philosophy, refactoring-patterns, system-design, ddia-systems, release-it, pragmatic-programmer - every phase carries its method inline so it runs standalone, asking the user questions at every decision point and recording results in the project docs/ folder (PERFORMANCE.md, ARCHITECTURE.md, ARCHITECTURE-OPTIMIZATION-PLAN.md) so the journey resumes across sessions. Use when the user wants to make an app faster, untangle drifted boundaries, fix slow endpoints and queries, or says ''it works but it is slow and getting worse''. For an untested prototype, improve-code-quality; for an aged codebase you fear to touch, remove-technical-debt; for greenfield structure, design-code-architecture; for marketing-site page speed, improve-website. For one framework in isolation, invoke that skill directly.
  • Aarchitecture-optimizationGuided journey from a working codebase grown slow and tangled to one measurably fast, cleanly bounded, and readable. Orchestrates eight skills phase by phase - working-with-legacy-code, clean-architecture, software-design-philosophy, refactoring-patterns, system-design, ddia-systems, release-it, pragmatic-programmer - every phase carries its method inline so it runs standalone, asking the user questions at every decision point and recording results in the project docs/ folder (PERFORMANCE.md, ARCHITECTURE.md, ARCHITECTURE-OPTIMIZATION-PLAN.md) so the journey resumes across sessions. Use when the user wants to make an app faster, untangle drifted boundaries, fix slow endpoints and queries, or says ''it works but it is slow and getting worse''. For an untested prototype, improve-code-quality; for an aged codebase you fear to touch, remove-technical-debt; for greenfield structure, design-code-architecture; for marketing-site page speed, improve-website. For one framework in isolation, invoke that skill directly.
  • Ablue-ocean-strategyCreate uncontested market space using value innovation instead of competing head-to-head. Use when the user mentions "blue ocean", "red ocean", "strategy canvas", "ERRC framework", "value innovation", "non-customers", "buyer utility map", "the market is too crowded", "how do we stand out", or "escape the price war". Also trigger when exploring a new market category, or finding underserved or non-customers. Covers the Four Actions Framework, Six Paths, buyer utility map, and value-cost trade-offs. For real strategy formulation and bad-strategy detection, see good-strategy-bad-strategy. For tech adoption strategy, see crossing-the-chasm. For product positioning, see obviously-awesome.
  • Ablue-ocean-strategyCreate uncontested market space using value innovation instead of competing head-to-head. Use when the user mentions "blue ocean", "red ocean", "strategy canvas", "ERRC framework", "value innovation", "non-customers", "buyer utility map", "the market is too crowded", "how do we stand out", or "escape the price war". Also trigger when exploring a new market category, or finding underserved or non-customers. Covers the Four Actions Framework, Six Paths, buyer utility map, and value-cost trade-offs. For real strategy formulation and bad-strategy detection, see good-strategy-bad-strategy. For tech adoption strategy, see crossing-the-chasm. For product positioning, see obviously-awesome.
  • Ablue-ocean-strategyCreate uncontested market space using value innovation instead of competing head-to-head. Use when the user mentions "blue ocean", "red ocean", "strategy canvas", "ERRC framework", "value innovation", "non-customers", "buyer utility map", "the market is too crowded", "how do we stand out", or "escape the price war". Also trigger when exploring a new market category, or finding underserved or non-customers. Covers the Four Actions Framework, Six Paths, buyer utility map, and value-cost trade-offs. For real strategy formulation and bad-strategy detection, see good-strategy-bad-strategy. For tech adoption strategy, see crossing-the-chasm. For product positioning, see obviously-awesome.
  • Aclean-architectureStructure software around the Dependency Rule: source code dependencies point inward from frameworks to use cases to entities. Use when the user mentions "architecture layers", "dependency rule", "ports and adapters (hexagonal)", "onion architecture", "screaming architecture", "where should business logic go", "decouple from the database", "swap the framework without a rewrite", or "keep business rules independent". Also trigger when deciding which layer code belongs in, isolating core logic from infrastructure, defining module boundaries, or debating whether the framework should call your code or the reverse. Covers component principles, boundaries, and SOLID. For code-level quality, see clean-code. For domain modeling, see domain-driven-design.
  • Aclean-architectureStructure software around the Dependency Rule: source code dependencies point inward from frameworks to use cases to entities. Use when the user mentions "architecture layers", "dependency rule", "ports and adapters (hexagonal)", "onion architecture", "screaming architecture", "where should business logic go", "decouple from the database", "swap the framework without a rewrite", or "keep business rules independent". Also trigger when deciding which layer code belongs in, isolating core logic from infrastructure, defining module boundaries, or debating whether the framework should call your code or the reverse. Covers component principles, boundaries, and SOLID. For code-level quality, see clean-code. For domain modeling, see domain-driven-design.
  • Aclean-architectureStructure software around the Dependency Rule: source code dependencies point inward from frameworks to use cases to entities. Use when the user mentions "architecture layers", "dependency rule", "ports and adapters (hexagonal)", "onion architecture", "screaming architecture", "where should business logic go", "decouple from the database", "swap the framework without a rewrite", or "keep business rules independent". Also trigger when deciding which layer code belongs in, isolating core logic from infrastructure, defining module boundaries, or debating whether the framework should call your code or the reverse. Covers component principles, boundaries, and SOLID. For code-level quality, see clean-code. For domain modeling, see domain-driven-design.

All agent skills → · MCP servers