design-patterns
Reusable solutions to common software design problems using established architectural patterns
ソース情報
- リポジトリ
- ffsshhttiikk/opencode-agents-skills
- ソースの最終更新活動
- 2026年2月28日 22:54
- 検出された SKILL.md の言語
- 英語
- スター
- 3
- フォーク
- 2
インストール方法
デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。
ソースファイルを確認
インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。
SKILL.md を表示中
SKILL.md
ソースの指示 · 読み取り専用プレビュー- name
- Design Patterns
- description
- Reusable solutions to common software design problems using established architectural patterns
- category
- software-development
# Design Patterns
## What I do
I provide proven, reusable solutions to recurring software design problems. Design patterns are not finished code but templates for how to solve a problem in a way that is reusable and maintainable. They represent best practices evolved over time by experienced developers facing similar challenges. I help you identify appropriate patterns for your specific context, implement them correctly, and combine them effectively to build robust software architectures.
## When to use me
Use design patterns when you encounter common architectural problems that have known solutions. Patterns are most valuable when you have a team because they provide a shared vocabulary and standard approach to solving problems. Apply patterns when building complex systems that need to be extensible, when you need to communicate design intent clearly to other developers, or when you want to leverage battle-tested solutions rather than reinventing solutions. Avoid over-engineering simple applications with unnecessary patterns.
## Core Concepts
- **Creational Patterns**: Factory Method, Abstract Factory, Builder, Singleton, Prototype
- **Structural Patterns**: Adapter, Bridge, Composite, Decorator, Facade, Flyweight, Proxy
- **Behavioral Patterns**: Chain of Responsibility, Command, Interpreter, Iterator, Mediator, Memento, Observer, State, Strategy, Template Method, Visitor
- **Pattern Intent**: The core problem each pattern solves
- **Participants**: The classes and objects involved in a pattern
- **Collaborations**: How participants work together
- **Consequences**: Trade-offs of using a pattern
- **Implementation**: Practical considerations for code
- **Related Patterns**: Connections between patterns
## Code Examples
### Factory Method Pattern
```python
from abc import ABC, abstractmethod
from typing import Optional
class Document(ABC):
@abstractmethod
def create_page(self) -> str:
pass
class Resume(Document):
def create_page(self) -> str:
return "Resume page with personal info, experience, education"
class Report(Document):
def create_page(self) -> str:
return "Report page with title, author, sections"
class DocumentFactory:
_registry: dict[str, type[Document]] = {}
@classmethod
def register(cls, doc_type: str, doc_class: type[Document]) -> None:
cls._registry[doc_type] = doc_class
@classmethod
def create(cls, doc_type: str) -> Document:
if doc_type not in cls._registry:
raise ValueError(f"Unknown document type: {doc_type}")
return cls._registry[doc_type]()
DocumentFactory.register("resume", Resume)
DocumentFactory.register("report", Report)
resume = DocumentFactory.create("resume")
print(resume.create_page())
```
### Strategy Pattern
```python
from abc import ABC, abstractmethod
from typing import Protocol
class PaymentStrategy(Protocol):
def pay(self, amount: float) -> bool:
...
class CreditCardPayment:
def __init__(self, card_number: str, expiry: str, cvv: str):
self.card_number = card_number
self.expiry = expiry
self.cvv = cvv
def pay(self, amount: float) -> bool:
print(f"Processing credit card payment of ${amount}")
return True
class PayPalPayment:
def __init__(self, email: str):
self.email = email
def pay(self, amount: float) -> bool:
print(f"Processing PayPal payment of ${amount} for {self.email}")
return True
class ShoppingCart:
def __init__(self):
self.items: list[tuple[str, float]] = []
self._payment_strategy: Optional[PaymentStrategy] = None
def add_item(self, name: str, price: float) -> None:
self.items.append((name, price))
def set_payment_strategy(self, strategy: PaymentStrategy) -> None:
self._payment_strategy = strategy
def checkout(self) -> bool:
total = sum(price for _, price in self.items)
if not self._payment_strategy:
raise ValueError("No payment strategy set")
return self._payment_strategy.pay(total)
cart = ShoppingCart()
cart.add_item("Book", 29.99)
cart.set_payment_strategy(CreditCardPayment("1234", "12/25", "123"))
cart.checkout()
```
### Observer Pattern
```python
from abc import ABC, abstractmethod
from typing import Protocol
class StockObserver(Protocol):
def update(self, symbol: str, price: float) -> None:
...
class StockMarket:
def __init__(self):
self._observers: list[StockObserver] = []
self._stock_prices: dict[str, float] = {}
def register(self, observer: StockObserver) -> None:
self._observers.append(observer)
def unregister(self, observer: StockObserver) -> None:
self._observers.remove(observer)
def set_price(self, symbol: str, price: float) -> None:
self._stock_prices[symbol] = price
self._notify(symbol, price)
def _notify(self, symbol: str, price: float) -> None:
for observer in self._observers:
observer.update(symbol, price)
class Investor:
def __init__(self, name: str):
self.name = name
def update(self, symbol: str, price: float) -> None:
print(f"Investor {self.name}: {symbol} is now ${price:.2f}")
market = StockMarket()
market.register(Investor("Alice"))
market.register(Investor("Bob"))
market.set_price("AAPL", 150.00)
```
### Decorator Pattern
```python
from abc import ABC, abstractmethod
from typing import Protocol
class Coffee(Protocol):
def get_description(self) -> str:
pass
def get_cost(self) -> float:
pass
class Espresso:
def get_description(self) -> str:
return "Espresso"
def get_cost(self) -> float:
return 2.00
class CoffeeDecorator(Coffee):
def __init__(self, coffee: Coffee):
self._coffee = coffee
def get_description(self) -> str:
return self._coffee.get_description()
def get_cost(self) -> float:
return self._coffee.get_cost()
class Milk(CoffeeDecorator):
def get_description(self) -> str:
return self._coffee.get_description() + ", Milk"
def get_cost(self) -> float:
return self._coffee.get_cost() + 0.50
class Sugar(CoffeeDecorator):
def get_description(self) -> str:
return self._coffee.get_description() + ", Sugar"
def get_cost(self) -> float:
return self._coffee.get_cost() + 0.25
coffee = Sugar(Milk(Espresso()))
print(f"{coffee.get_description()}: ${coffee.get_cost():.2f}")
```
### Singleton Pattern
```python
class DatabaseConnection:
_instance: 'DatabaseConnection | None' = None
_connection: str | None = None
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
def connect(self, db_name: str) -> None:
if self._connection:
raise RuntimeError("Already connected")
self._connection = f"Connection to {db_name}"
print(f"Connected to {db_name}")
def query(self, sql: str) -> list[dict]:
if not self._connection:
raise RuntimeError("Not connected")
print(f"Executing: {sql}")
return [{"id": 1, "name": "Sample"}]
db1 = DatabaseConnection()
db1.connect("production_db")
db2 = DatabaseConnection()
print(db1 is db2)
db2.connect("another_db")
```
## Best Practices
1. **Start Simple**: Don't apply patterns prematurely; solve problems with simple code first
2. **Know the Trade-offs**: Every pattern has benefits and costs; understand both before applying
3. **Prefer Composition**: Favor object composition over class inheritance when possible
4. **Avoid God Objects**: Don't let one class know too much or do too much
5. **Keep Cohesion High**: Related functionality should be grouped together
6. **Minimize Coupling**: Reduce dependencies between modules
7. **Open/Closed Principle**: Software should be open for extension, closed for modification
8. **Use Patterns as Vocabulary**: Share pattern names to communicate intent clearly
9. **Refactor to Patterns**: Apply patterns during refactoring, not initial design
10. **Combine Patterns Wisely**: Multiple patterns often work together; understand their interactions
GitHubで見る