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.
Applies Pythonic design patterns and SOLID principles when discussing factory, strategy, observer, or other GoF patterns. Provides idiomatic alternatives like using Callables instead of strategy objects and module-level instances instead of singleton classes.
/plugin marketplace add WorldCentralKitchen/python-dev-framework/plugin install worldcentralkitchen-python-dev-framework@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 |
This skill should be used when the user asks to "create a slash command", "add a command", "write a custom command", "define command arguments", "use command frontmatter", "organize commands", "create command with file references", "interactive command", "use AskUserQuestion in command", or needs guidance on slash command structure, YAML frontmatter fields, dynamic arguments, bash execution in commands, user interaction patterns, or command development best practices for Claude Code.
This skill should be used when the user asks to "create an agent", "add an agent", "write a subagent", "agent frontmatter", "when to use description", "agent examples", "agent tools", "agent colors", "autonomous agent", or needs guidance on agent structure, system prompts, triggering conditions, or agent development best practices for Claude Code plugins.
This skill should be used when the user asks to "create a hook", "add a PreToolUse/PostToolUse/Stop hook", "validate tool use", "implement prompt-based hooks", "use ${CLAUDE_PLUGIN_ROOT}", "set up event-driven automation", "block dangerous commands", or mentions hook events (PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification). Provides comprehensive guidance for creating and implementing Claude Code plugin hooks with focus on advanced prompt-based hooks API.