💡
デザインパターンを学ぶ #5 Decorator(デコレーター)
1. はじめに
デザインパターン学習シリーズの第5回。今回は「Decorator(デコレーター)」パターンを取り上げます。
目的は「既存のクラスを変更せずに、機能を後付けで追加する方法」を理解することです。
2. Decorator とは?
Decorator パターンは「元のオブジェクトをラップして、処理を委譲しつつ追加機能を差し込む」仕組みです。
継承を使わずに柔軟な拡張ができ、必要な分だけ積み重ねることができます。
例えば通知処理において「基本の通知」に加えて「Slack へも通知」「Email へも通知」を足したいとき、Decorator を使えば if 文を増やさず拡張できます。
3. 実装例(PHP)
interface Notifier {
public function send(string $message): void;
}
class BasicNotifier implements Notifier {
public function send(string $message): void {
echo "Send: {$message}\n";
}
}
abstract class NotifierDecorator implements Notifier {
protected Notifier $wrappee;
public function __construct(Notifier $notifier) {
$this->wrappee = $notifier;
}
}
class SlackNotifier extends NotifierDecorator {
public function send(string $message): void {
$this->wrappee->send($message);
echo "Also send to Slack: {$message}\n";
}
}
class EmailNotifier extends NotifierDecorator {
public function send(string $message): void {
$this->wrappee->send($message);
echo "Also send Email: {$message}\n";
}
}
// 利用例
$notifier = new EmailNotifier(
new SlackNotifier(
new BasicNotifier()
)
);
$notifier->send("System down!");
出力例
Send: System down!
Also send to Slack: System down!
Also send Email: System down!
4. メリットと注意点
メリット
- 既存コードを変更せず拡張できる
- 必要な機能を積み重ねて組み合わせられる
- 実行時に差し替えが可能で柔軟
注意点
- デコレーターが増えるとクラス数が膨らむ
- ラップの順番依存が発生する可能性がある
5. 実務での利用例
- 通知処理(基本 → Slack → Email → Push通知を積み重ね)
- ログ記録やメトリクス収集の追加
- キャッシュやリトライの横断的な処理を足す
6. まとめ
Decorator パターンは「既存の処理をラップし、前後に機能を追加する」仕組みです。
継承せずに拡張できるため、横断的な処理を積み木のように組み合わせたいときに役立ちます。
Discussion