デコレータパターン

この記事で紹介するパターン

デコレータ(Decorator) パターン

どんなデザインパターン?

・ある既存のクラスに対して機能追加を行うためのパターン
・既存のクラスに対しては手を入れない

既存クラスに手を入れず機能追加を行う方法は?

・デコレータクラスを作って既存クラスのインスタンスを渡し、デコレータクラスに機能追加や機能拡張を書いていく

と書いてみたものの、ウェキペディアにわかりやすい?説明があった。

Decorator パターンの方針は、既存のオブジェクトを新しい Decorator オブジェクトでラップすることである。 その方法として、Decorator のコンストラクタの引数でラップ対象の Component オブジェクトを読み込み、コンストラクタの内部でそのオブジェクトをメンバに設定することが一般的である。

何が良いのか?

・上で何度も行っているとおりで既存のクラスに手を入れなくても良い点

Rubyのコードで簡単な例を紹介してみる

登場人物
・Dogクラス(手を入れたい既存のクラス)
・DogDecoratorクラス(Dogクラスに機能を追加するためのクラス)

Dogクラス

現状ワンワンと鳴くインスタンスメソッドが定義されているのみ。

次にDogクラスの機能を追加するためのデコレータクラスを準備する

Dogオブジェクトを保持し、barkメソッドやnameメソッドを@dog.barkや@dog.nameに移譲しているのがポイント。
これで、Dogオブジェクト(既存のクラス)と同等の振る舞いをするオブジェクトを作れた。
コンソールで試してみると以下のとおり。

ここからはデコレータクラスにメソッドを追加したり、メソッドの振る舞いを変えたり好きなようにすればよい。

Dogクラスはそのままで、デコレータクラスを以下のようにする

コンソールで試してみる。

機能追加、機能拡張できた。

まとめ

・Dogクラスに手を入れることなく、Dogクラスに機能を追加できる
・もっと良いコードの例があった気がするがまあこれで良いとする
・Railsでファットモデルに対する対策としてhttps://github.com/amatsuda/active_decorator
などを入れてビューの表示に関するメソッドをデコレータクラスで管理したりをよくするが、おそらくこのデコレータパターンを使っている(と思う)

スポンサーリンク
スポンサーリンク
スポンサーリンク

シェアする

  • このエントリーをはてなブックマークに追加

フォローする

スポンサーリンク
スポンサーリンク