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.
Explains and implements Pythonic design patterns, SOLID principles, and anti-patterns for clean, idiomatic code.
npx claudepluginhub worldcentralkitchen/python-dev-frameworkThis skill inherits all available tools. When active, it can use any tool Claude has access to.
references/patterns.mdreferences/python-idioms.mdreferences/solid-anti.mdPythonic 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.
| 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() |
| 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-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 |
# 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: 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: 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
| 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 |
Activates when the user asks about AI prompts, needs prompt templates, wants to search for prompts, or mentions prompts.chat. Use for discovering, retrieving, and improving prompts.
Search, retrieve, and install Agent Skills from the prompts.chat registry using MCP tools. Use when the user asks to find skills, browse skill catalogs, install a skill for Claude, or extend Claude's capabilities with reusable AI agent components.
Creating algorithmic art using p5.js with seeded randomness and interactive parameter exploration. Use this when users request creating art using code, generative art, algorithmic art, flow fields, or particle systems. Create original algorithmic art rather than copying existing artists' work to avoid copyright violations.