GoFデザインパターン23個を完全に理解するブログ #09 Decorator(デコレーター)

2025/11/04

プログラミング

t f B! P L
eyecatch 「構造パターン」の中でも実用頻度が非常に高い、Decorator(デコレーター)パターンをわかりやすく解説します。 このパターンは、既存のオブジェクトに新しい機能を“動的に”追加するためのパターンです。 コーヒーに「ミルク」「砂糖」「シナモン」を後から追加する感じでイメージしてみましょう。

よくある例

ログ出力に「タイムスタンプ」や「ファイル名」を追加する場合に使われます。 データ送信に「暗号化」「圧縮」処理を後付けする場合など。 ReactのHOC(高階コンポーネント)や、Pythonの@decoratorも概念的に同じ。
分野 Compositeの実例
Web開発 Express.jsのmiddlewareチェーン
React HOC(Higher-Order Component)構造
ログ処理 ロガーに「日付」「色」「保存先」を後付け
通信 データ送信に暗号化や圧縮を追加
ゲーム開発 キャラに「スピードアップ」「防御力アップ」を動的に付与

サンプルコード

例)メッセージを送信するクラスに、機能を「後付け」する。

基本クラス(Component)

class Notifier { send(message) { console.log(`通知: ${message}`); } }

デコレーターの基底クラス(Componentと同じインターフェース)

class NotifierDecorator { constructor(notifier) { this.notifier = notifier; } send(message) { this.notifier.send(message); } }

追加機能①:Slack送信を追加

class SlackNotifier extends NotifierDecorator { send(message) { super.send(message); console.log(`→ Slackに送信: ${message}`); } }

追加機能②:メール送信を追加

class EmailNotifier extends NotifierDecorator { send(message) { super.send(message); console.log(`→ メールに送信: ${message}`); } }

実行例

let notifier = new Notifier(); notifier = new SlackNotifier(notifier); notifier = new EmailNotifier(notifier); notifier.send("デプロイが完了しました。");

出力結果

通知: デプロイが完了しました。 → Slackに送信: デプロイが完了しました。 → メールに送信: デプロイが完了しました。

ポイント解説

・Notifier(基本機能)に対して、SlackNotifierやEmailNotifierがラップして拡張している。 ・クラスを継承せずに機能追加できるのが最大の特徴。 ・どのデコレーターを重ねても、同じインターフェース(send())で呼べる。

メリット

・オブジェクト単位で柔軟に機能拡張できる。 ・継承よりも組み合わせの自由度が高い。 ・元クラスを一切変更せず、オープン・クローズド原則に適合。

デメリット

・デコレーターを多重に重ねると呼び出し順がわかりづらい。 ・デバッグ時に「今どのデコレーターが作用しているか」を追うのが大変。 ・過剰なラップ構造は複雑化の原因になる。

あとがき

Compositeとの違いは、以下のとおりです。
比較項目 Composite Decorator
構造目的 階層構造を表現する(ツリー) 機能を重ねて追加する(ラップ)
主な関係 子を持つ親(再帰的) 元オブジェクトを包む(入れ子)
主な操作 再帰的な処理 チェーン的な処理
作られたインスタンスを、どんどんDecoratorしたインスタンスで上書きしていき、 最終実行する際に、一括処理できる点が少し複雑ですが、理解できると、複数処理をまとめる時に使えます。 Compositeしたリソースを、一括処理するようなイメージで使えそうですね。 複雑に感じる人は、自分でコードを書いて実装経験を積んで理解するのがいいですね。

人気の投稿

このブログを検索

ごあいさつ

このWebサイトは、独自思考で我が道を行くユゲタの少し尖った思考のTechブログです。 毎日興味がどんどん切り替わるので、テーマはマルチになっています。 もしかしたらアイデアに困っている人の助けになるかもしれません。

ブログ アーカイブ