
Python Design Patterns
Apply KISS, SRP, and composition-over-inheritance when structuring Python services, refactors, and PR reviews so logic stays testable and decoupled from I/O.
Overview
Python Design Patterns is an agent skill most often used in Build (also Ship review, Operate iterate) that applies KISS, SRP, and composition-over-inheritance when designing or refactoring Python code.
Install
npx skills add https://github.com/wshobson/agents --skill python-design-patternsWhat is this skill?
- Covers KISS, Single Responsibility, Separation of Concerns, and composition over inheritance
- Triggers for greenfield design, God-class refactors, abstraction-vs-duplication tradeoffs
- Pull-request lens for tight coupling and leaking internal types
- Guidance when tests fail because business logic is entangled with I/O
- 4 named core concepts: KISS, SRP, Separation of Concerns, composition over inheritance
Adoption & trust: 12.7k installs on skills.sh; 36.5k GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
Your Python module grew into a God class or a single function that mixes I/O with business rules, so every change breaks tests and reviews miss coupling.
Who is it for?
Solo builders shipping FastAPI, Django, or script-backed APIs who want consistent structural guidance without adopting a heavy framework.
Skip if: Teams that only need one-off syntax help or language trivia with no service boundaries to design.
When should I use this skill?
Designing a new service or component, refactoring a God class, deciding abstraction vs duplication, evaluating PRs for structural issues, or when I/O and business logic are entangled and hard to test.
What do I get? / Deliverables
You get clearer module boundaries, simpler abstractions, and review-ready reasoning for inheritance versus composition on the next change set.
- Refactor plan with bounded responsibilities
- PR review notes on coupling and abstraction choices
Recommended Skills
Journey fit
Spans multiple journey phases - primary shelf plus alternate fits below.
New components and modular architecture land in Build; the skill’s primary shelf is backend Python structure before shipping. Backend is where services, God-class refactors, and I/O-vs-business layering decisions usually happen for solo Python apps.
Where it fits
Split a FastAPI handler that reads disks, validates, and persists into focused units before adding a second endpoint.
Flag a PR that exposes ORM models through the public API surface.
Choose composition to add a new notification channel without subclassing a brittle base service.
How it compares
Use as a design-principles coach during implementation and review—not as a linter replacement or auto-formatter.
Common Questions / FAQ
Who is python-design-patterns for?
Indie and solo Python developers designing services, refactoring large modules, or reviewing PRs for coupling and testability.
When should I use python-design-patterns?
During Build when layering a new component; during Ship review when a PR changes class hierarchies; during Operate iterate when production code is hard to extend safely.
Is python-design-patterns safe to install?
It is procedural guidance only; review the Security Audits panel on this Prism page before adding any skill to your agent workflow.
SKILL.md
READMESKILL.md - Python Design Patterns
# Python Design Patterns Write maintainable Python code using fundamental design principles. These patterns help you build systems that are easy to understand, test, and modify. ## When to Use This Skill - Designing new components or services - Refactoring complex or tangled code - Deciding whether to create an abstraction - Choosing between inheritance and composition - Evaluating code complexity and coupling - Planning modular architectures ## Core Concepts ### 1. KISS (Keep It Simple) Choose the simplest solution that works. Complexity must be justified by concrete requirements. ### 2. Single Responsibility (SRP) Each unit should have one reason to change. Separate concerns into focused components. ### 3. Composition Over Inheritance Build behavior by combining objects, not extending classes. ### 4. Rule of Three Wait until you have three instances before abstracting. Duplication is often better than premature abstraction. ## Quick Start ```python # Simple beats clever # Instead of a factory/registry pattern: FORMATTERS = {"json": JsonFormatter, "csv": CsvFormatter} def get_formatter(name: str) -> Formatter: return FORMATTERS[name]() ``` ## Detailed patterns and worked examples Detailed pattern documentation lives in `references/details.md`. Read that file when the navigation tier above is insufficient. ## Best Practices Summary 1. **Keep it simple** - Choose the simplest solution that works 2. **Single responsibility** - Each unit has one reason to change 3. **Separate concerns** - Distinct layers with clear purposes 4. **Compose, don't inherit** - Combine objects for flexibility 5. **Rule of three** - Wait before abstracting 6. **Keep functions small** - 20-50 lines (varies by complexity), one purpose 7. **Inject dependencies** - Constructor injection for testability 8. **Delete before abstracting** - Remove dead code, then consider patterns 9. **Test each layer** - Isolated tests for each concern 10. **Explicit over clever** - Readable code beats elegant code ## Troubleshooting **A class is growing and seems to have multiple responsibilities, but splitting it feels wrong.** Apply the "reason to change" test: list every change that could require editing this class. If the list has items from different domains (e.g., HTTP parsing AND business rules AND formatting), split it. If all changes stem from the same domain concern, the class may be appropriately sized. **Injecting all dependencies through the constructor is producing constructors with 7+ parameters.** This is a sign of too many responsibilities in one class, not a problem with dependency injection. Split the class into smaller units first, then each constructor naturally becomes smaller. **Composition is producing deeply nested wrapper objects that are hard to trace.** Keep the composition shallow (2-3 levels). If wrapping is the only mechanism, consider whether a Protocol-based approach or simple function composition would be cleaner than a chain of decorator objects. **The rule of three says not to abstract yet, but the duplication is causing bugs when one copy is updated but not the other.** Duplication that diverges in dangerous ways should be abstracted sooner. The rule of three is a heuristic, not a law. If the copies are already diverging in