2007年08月09日

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

 今回は、デコレータパターンのお話です。
デコレータパターンは、オブジェクトに自由に振る舞いを追加する方法です。
以下のような特徴を持っています。
  • 振る舞いを追加してもしなくても、クライアントは違いを気にしないで済む
  • 振る舞いを動的に追加することができる
  • 対象のオブジェクトを小さく保つことができる

これらの特徴を一つずつ探っていきましょう。

コンテンツ

  1. ポイントカードシステム
  2. クライアントは違いを全く気にしないで済む
  3. る舞いを動的に追加することができる
  4. 対象のオブジェクトを小さく保つことができる
  5. デコレータパターンのしくみ
  6. 他のパターンとの関係
  7. オススメ

ポイントカードシステム

 ヨド○シカメラとかさく○やとかの量販店には、よくポイントカードってのがありますね。
ポイントカードって、なんのためにあるんでしょう?
ポイント還元で割引みたいなことをする、サービスのため?
いえいえ、それも重要なことですが、本質ではありません。

 ポイントカードの本質は、顧客管理にあります。
ポイントカードを作るとき、皆さんは申し込み用紙に住所、氏名、生年月日など、いろいろな個人情報を記入したはずです。
あれをデータベース化して、顧客を管理することが本質なのです。
この、ポイントカードというアイテムで顧客管理をするシステムのことを、ここではポイントカードシステムと呼ぶことにします。
今回は、このポイントカードシステムを例にとって、デコレータパターンを考えてみましょう。

 ポイントカードシステムの素晴らしいところは、管理の対象となる顧客全員が、自分を識別するためのカードを持っていてくれることです。
顧客は、自分がデータベース上のどの記録にあたるのかを識別するために、自らカードを提示してくれます。
データベースを照合して、顧客の記録を確実に取り出すことができるということは、顧客サービスを的確に提供する上で、非常に大きな武器になります。
いったんこのシステムを導入してしまうと、顧客に対するいろいろなサービスを、簡単確実に追加できるようになるのです。

クライアントは違いを全く気にしないで済む

 ポイントカードシステムの本質は顧客管理であることは、既に言いましたね。
つまり、ポイントカードシステムという名前ではありますが、実際にはポイント還元サービスはなくてもいいんです。
カードとデータベースさえあればいいんです。

 さて、もしポイント還元サービスがなかったとしたら、顧客であるあなたにとって、何が変わるんでしょうか?
もちろん、お得感が違いますね。
お得でなければ、わざわざ個人情報を明かしたり、カードを持ち歩いたりする気にはなれませんよね。
この2点―顧客に個人情報を明かしてもらうことと、自分自身を識別するためのカードを持ち歩いてもらうことは、ポイント還元サービスの重要な目的です。

 でも、これらは本題とは関係ありません。
こういうキモチの問題は別にして、あなたが商品を買うときにすることは、何か変わるのでしょうか?
欲しい商品をレジに持っていって、カードを提示して、お金を払う。
ポイント還元サービスがあろうがなかろうが、このことには、何ら変わりがありませんね。
あなたは、何も気にすることなく、以前から使っているポイントカードを提示するだけです。
クライアントは違いを全く気にしないで済むわけです。

振る舞いを動的に追加することができる

 「動的」って、なんでしょう?
動的って、ダイナミックということです。
振る舞いをダイナミックに追加することができるというわけです。

 ソフトウェア開発に関して言うなら、動的というのは、普通「実行時に」ということになります。
この場合、コンパイル時にはどの振る舞いを追加するのか、あるいはしないのか決定せずに、実行時に振る舞いを追加するということになります。

 例えば、来月はキャンペーンで、15%を還元しましょうか?
来月一日から還元ポイントを15%にして、再来月の一日からは、また元の還元率に戻すわけですね。
そんなの簡単です。
ポイント還元率は、必要ならいつでも変更することができます。
このとき、ポイントカードシステムに変更を加える必要は全くありません。
(ソフトウェアを変更することなしに還元ポイントを変える方法は、デコレータパターン以外にもいくつかありますが、それは今回の話題とは関係ありませんので、説明しません)
振る舞いを動的に追加することができるのです。

対象のオブジェクトを小さく保つことができる

 さて、今度はポイントではなく、新しいサービスを導入することになりました。
品質保証サービスです。
メーカーの保証期間が切れても、一定の期間内は店側で保証し、修理費を負担するサービスです。
これも、顧客管理を土台として提供できるサービスですね。

 で、このサービスを開始するにあたっては、今までのポイントカードとは別に、品質保証サービスのためのカードを発行する必要があると思いますか?
そんなはずありませんよね。
従来のポイントカードが提示されれば、あなたがどの顧客なのか、店は確認することができます。
品質保証サービスは、それだけで提供できるはずです。

このように、ポイントカード一枚あれば、後からいろいろなサービスを展開することができます。
いろんなサービスを追加しても、ポイントカードシステムという対象のオブジェクトを小さく保つことができるわけです。

デコレータパターンのしくみ

 今回の例では、いろいろな還元率でのポイント還元や品質保証など、付加サービスがデコレータです。
ポイントカードシステムが、デコレートされる対象のオブジェクトですね。
あなたがポイントカードシステムを提示するという行為が、インターフェイスです。
サービスがどれだけくっついても、あなたがポイントカードを提示するというインターフェイスは、全く変わることがないわけです。

 乱暴に言ってしまうと、要するにぺたぺたと後からいろんなものをくっつけられるような仕組みが、デコレータパターンです。
デコレータパターンで解釈するとすっきり理解できるものは、他にもいろいろあるのではないでしょうか。
ちょっと探してみてください。


 デコレータパターンでは、デコレータと呼ばれるオブジェクトを用意します。
デコレータは対象オブジェクトと同じスーパークラスから派生するか、または同じインターフェイスをインプリメントしたものです。
ですので、クライアントからは対象オブジェクトもデコレータも同じように見えます。
デコレータは対象オブジェクトを包含し、ほとんどの振る舞いを対象オブジェクトにそのまま委譲します。
何か追加する必要がある振る舞いでのみ、対象オブジェクトに委譲する前か後に、オリジナルの振る舞いを行います。
この結果、クライアントと対象オブジェクトの両方とも、相手がデコレータであるということに影響されることがありません。

 対象オブジェクトは、最も本質的な振る舞いだけを持つように分析/設計しておき、付加的な振る舞いは全てデコレータにすることができます。
これにより、対象オブジェクトを小さく保つことができます。

他のパターンとの関係

 構造の面からいうと、デコレータパターンは、コンポジットパターンプロキシパターンアダプタパターンとよく似ています。
これらは、全てオブジェクトを包含するパターンだからです。
しかし、目的はそれぞれ全く違います。
コンポジットパターンはシステムの構造を表現すること、プロキシパターンはオブジェクトへのアクセスを制御すること、アダプタパターンはオブジェクトのインターフェイスを変換することが目的です。
デコレータパターンは、構造ではなく、あくまで振る舞いに着目しています。
オブジェクトのインターフェイスを変更することなしに、振る舞いを追加することが目的なのです。

 とはいえ、構造が似ていることで、デコレータパターンがこれらのパターンと連携しやすいことは確かです。
コンポジットパターンで構成されたシステム内のオブジェクトをデコレートしたり、振る舞いも追加するプロキシやアダプタなど、デコレータパターンと他のパターンのいろいろな混合物が考えられます。
パターンは言語であり、単語にあたる各パターンが連携し合って、フレーズになるということの一端ですね。

オススメ

 オブジェクト思考における再利用のためのデザインパターンで、今回お話ししたデコレータパターンを含め、GoFの全てのデザインパターンを学べます。
私も、この本で全て学びました。

 前半では、そもそもデザインパターンをはじめとするソフトウェアパターンとは何なのかについて解説されています。

 既に確立された解決法を無視して、同じものを自前で一から作っちゃうことを、俗に車輪の再発明と言います。
いろいろなパターンを学ぶことは、これを避ける意味で、非常に重要です。

 でも、パターンを自分で作れるようになることで、更なる恩恵を享受できるようになります。
プログラムの再利用法には、オープンソースや市販のフレームワークやコンポーネントなどによる組織を越えた再利用と、社内のリポジトリなどによる組織内での再利用があります。

 パターンは、分析や設計を再利用するための方法です。
そして、一般に発表されているパターンを学ぶことは、組織を越えた再利用にあたります。
パターンを自分で作れるようになれば、組織内でも、分析や設計を再利用できるようになるのです。

 そういう意味で、この本は後半の有名なGoFのデザインパターンカタログだけでなく、前半も非常に重要です。
派手でわかりやすいところばかりでなく、ぜひ本質をつかんでください。

posted by craftsman at 04:13 | 東京 ☁ | Comment(2) | TrackBack(0) | デザインパターン
この記事へのコメント
『デザーンパターン』を検索していてここに辿り着きました。
とても分かりやすく解説されていて、SE/PG駆け出しの私にも理解することができました!
ありがとうございます!!
いろんなカテゴリでブログ書いていらっしゃるとは思いますが、デザインパターンについてもまた載せてくださると嬉しいですっっ
Posted by Maron at 2009年07月28日 10:27
はじめまして、Maronさん。
craftsmanです。

とてもうれしいお言葉、こちらこそありがとうございます。
まだ触れてないデザインパターンについても、今後書いていくつもりでいます。
なかなかペースは上がりませんが、また思い出したら、ここを覗いてみてくださるとうれしいです。
Posted by craftsman at 2009年07月28日 11:04
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント: [必須入力]

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。

この記事へのトラックバック
×

この広告は1年以上新しい記事の投稿がないブログに表示されております。