Agent skill
Python Design Patterns
This skill should be used when the user asks about "design patterns", "SOLID principles", "factory pattern", "strategy pattern", "observer pattern", "composition vs inheritance", "Pythonic design", "singleton alternatives", "anti-patterns", "dependency injection", or needs guidance on applying Gang of Four patterns idiomatically in Python.
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/design/python-design-patterns-worldcentralkitchen-python-dev-framework
SKILL.md
Python Design Patterns
Pythonic adaptations of GoF patterns, SOLID principles, and anti-patterns to avoid.
"Modern Python simply avoids the problems that the old design patterns were meant to solve." — Brandon Rhodes, PyCon 2025
Prerequisites: from __future__ import annotations, collections.abc for Callable/Iterator, structlog for logging.
Pattern Decision Table
| Need | Pattern | Python Idiom |
|---|---|---|
| Multiple creation strategies | Factory | Function or @classmethod |
| Complex object, many options | Builder | dataclass + replace() |
| Interchangeable algorithms | Strategy | Pass Callable |
| Event notification | Observer | Callback list |
| Lazy sequences | Iterator | Generator (yield) |
| Tree structures | Composite | Recursive dataclass |
| Memory optimization | Flyweight | __slots__, lru_cache |
| Interface conversion | Adapter | Wrapper class |
| Cross-cutting concerns | Decorator | @decorator |
| State machines | State | Dict mapping or match |
| Shared configuration | Global Object | Module-level instance |
| Callbacks with state | Prebound Method | obj.method, partial |
| None is valid value | Sentinel | _MISSING = object() |
SOLID Quick Reference
| Principle | Violation Sign | Fix |
|---|---|---|
| Single Responsibility | "Manager" class | Split into focused classes |
| Open-Closed | if/elif on types |
Dict of handlers + Protocol |
| Liskov Substitution | NotImplementedError |
Composition over inheritance |
| Interface Segregation | Unused interface methods | Small Protocol classes |
| Dependency Inversion | self.db = PostgresDB() |
Constructor injection |
Anti-Patterns
| Anti-Pattern | Why Bad | Pythonic Alternative |
|---|---|---|
| Singleton class | Modules ARE singletons | Module-level instance |
| Deep inheritance | Coupling, diamond problem | Composition + Protocol |
| Java getters/setters | Boilerplate | Direct attrs, @property |
| God Object | Untestable, SRP violation | Focused services |
| Method without self | Unnecessary class | Module-level function |
| Premature patterns | Over-engineering | YAGNI - add when needed |
Key Patterns
Factory & Strategy
# Factory: function returning instance
def create_connection(db_type: str) -> Connection:
return {"postgres": PostgresConn, "sqlite": SQLiteConn}[db_type]()
# Strategy: pass functions, not strategy objects
def calculate_total(items: list[Item], pricing: Callable[[float], float]) -> float:
return sum(pricing(i.price) for i in items)
Observer & Decorator
# Observer: callback list
@dataclass
class EventEmitter:
_listeners: dict[str, list[Callable]] = field(default_factory=dict)
def on(self, event: str, fn: Callable) -> None:
self._listeners.setdefault(event, []).append(fn)
def emit(self, event: str, *args) -> None:
for fn in self._listeners.get(event, []): fn(*args)
# Decorator: @wraps for cross-cutting concerns
def timing(func):
@wraps(func)
def wrapper(*a, **kw):
start = perf_counter()
result = func(*a, **kw)
log.info("timing", elapsed=perf_counter() - start)
return result
return wrapper
Global Object & Sentinel
# Global Object: module-level instance (not singleton class)
_config: Config | None = None
def get_config() -> Config:
global _config
if _config is None: _config = Config.from_env()
return _config
# Sentinel: distinguish None from "not provided"
_MISSING = object()
def get(key: str, default: object = _MISSING) -> object:
if (v := cache.get(key)) is not None: return v
if default is _MISSING: raise KeyError(key)
return default
Reference Files
| File | Content |
|---|---|
references/patterns.md |
All GoF patterns with examples |
references/solid-anti.md |
SOLID principles + anti-patterns |
references/python-idioms.md |
Global Object, Prebound Method, Sentinel |
Related
- ADR-014 - Design decisions
- ADR-013 - Immutability patterns
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
Didn't find tool you were looking for?