Agent Skill
2/7/2026

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.

W
worldcentralkitchen
0GitHub Stars
1Views
npx skills add WorldCentralKitchen/python-dev-framework

SKILL.md

Namepython-design-patterns
DescriptionThis 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.

name: python-design-patterns description: > 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.

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

NeedPatternPython Idiom
Multiple creation strategiesFactoryFunction or @classmethod
Complex object, many optionsBuilderdataclass + replace()
Interchangeable algorithmsStrategyPass Callable
Event notificationObserverCallback list
Lazy sequencesIteratorGenerator (yield)
Tree structuresCompositeRecursive dataclass
Memory optimizationFlyweight__slots__, lru_cache
Interface conversionAdapterWrapper class
Cross-cutting concernsDecorator@decorator
State machinesStateDict mapping or match
Shared configurationGlobal ObjectModule-level instance
Callbacks with statePrebound Methodobj.method, partial
None is valid valueSentinel_MISSING = object()

SOLID Quick Reference

PrincipleViolation SignFix
Single Responsibility"Manager" classSplit into focused classes
Open-Closedif/elif on typesDict of handlers + Protocol
Liskov SubstitutionNotImplementedErrorComposition over inheritance
Interface SegregationUnused interface methodsSmall Protocol classes
Dependency Inversionself.db = PostgresDB()Constructor injection

Anti-Patterns

Anti-PatternWhy BadPythonic Alternative
Singleton classModules ARE singletonsModule-level instance
Deep inheritanceCoupling, diamond problemComposition + Protocol
Java getters/settersBoilerplateDirect attrs, @property
God ObjectUntestable, SRP violationFocused services
Method without selfUnnecessary classModule-level function
Premature patternsOver-engineeringYAGNI - 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

FileContent
references/patterns.mdAll GoF patterns with examples
references/solid-anti.mdSOLID principles + anti-patterns
references/python-idioms.mdGlobal Object, Prebound Method, Sentinel

Related

Skills Info
Original Name:python-design-patternsAuthor:worldcentralkitchen