概要
Decorator(デコレーター)パターンは、
あるオブジェクトに対して、元のインターフェースを保ったまま、機能を段階的に追加する構造パターンである。
継承ではなく構成(composition)を用いることで、既存コードの修正を一切加えずに柔軟な機能拡張を可能にする。
Pythonの文法におけるデコレーター構文(@
)とは異なるが、設計思想としては共通している。
1. なぜDecoratorが必要か?
❌ 機能追加のために継承を繰り返す構造
class Coffee:
def cost(self): return 300
class MilkCoffee(Coffee):
def cost(self): return super().cost() + 50
→ 継承チェーンが増えるほど、柔軟性が低下し組み合わせの爆発が起こる
✅ 機能をラップして動的に積み重ねる
coffee = MilkDecorator(SugarDecorator(PlainCoffee()))
coffee.cost() # → 拡張された合計
→ 拡張の順序・有無を自由にコントロール可能に
2. 基本構造
✅ Component(共通インターフェース)
class Beverage:
def cost(self):
raise NotImplementedError
✅ ConcreteComponent(元のオブジェクト)
class PlainCoffee(Beverage):
def cost(self):
return 300
✅ Decorator(共通のラッパー構造)
class CoffeeDecorator(Beverage):
def __init__(self, beverage: Beverage):
self._beverage = beverage
✅ ConcreteDecorators(拡張ロジック)
class MilkDecorator(CoffeeDecorator):
def cost(self):
return self._beverage.cost() + 50
class SugarDecorator(CoffeeDecorator):
def cost(self):
return self._beverage.cost() + 30
✅ 使用例
coffee = PlainCoffee()
print(coffee.cost()) # 300
decorated = MilkDecorator(SugarDecorator(coffee))
print(decorated.cost()) # 300 + 30 + 50 = 380
3. Python的応用:関数デコレーターと構造パターンの融合
def logging_decorator(func):
def wrapper(*args, **kwargs):
print(f"[LOG] 呼び出し: {func.__name__}")
return func(*args, **kwargs)
return wrapper
@logging_decorator
def greet(name):
print(f"Hello, {name}!")
greet("Alice")
# → [LOG] 呼び出し: greet
# → Hello, Alice!
→ 関数ベースでもDecorator思想を自然に適用可能
4. 実務ユースケース
✅ UIコンポーネントへの装飾
→ ボタンに影・枠・アイコンなどを動的に追加する
✅ 認証・ロギング・トレースの挿入
→ メソッドやサービスに関心の横断的機能を非侵入的に注入
✅ ミドルウェアの設計(例:Flask / Django)
→ リクエスト処理をチェーン構造で構築する
✅ ストリーム処理(ファイル→暗号化→圧縮)
→ 段階的な加工をDecoratorで表現
5. よくある誤用と対策
❌ 複数のデコレーターを順序依存で設計してしまう
→ ✅ 各Decoratorは順序に依存しない独立性を保つ設計を心がける
❌ Decoratorが元のインターフェースを壊してしまう
→ ✅ Decorator
は 元のメソッドと引数を忠実に模倣すべき
❌ Decoratorのネストが可読性を損なう
→ ✅ 構成順に名前を付けて変数に代入し、明示的なスタック構造に
結語
Decoratorパターンとは、“機能を段階的に包み込みながら拡張する柔構造設計”である。
- 継承に頼らず、構成とラップによって機能を動的に追加・削除できる
- 主処理と副作用(ログ・認証・スタイル等)を分離可能にし、再利用性を高める
- Pythonでは関数・クラスの両レベルで、デコレーターの思想を直感的に実装可能
Pythonicとは、“動的で柔軟な拡張性を最小限の変更で実現する”ことであり、
Decoratorパターンはその重ねられた機能美を、洗練されたレイヤーとしてコードに織り込む技法である。