2007年07月15日

Composite(コンポジット)パターン

 いよいよ、デザインパターンのお話をはじめます。

 パターンとは、「こんな場合、こうする」というかんじで、「こんな場合」にあたる問題と「こうする」にあたる解法がセットになったものです。
要するに、HowToですね。
このデザインパターンがいくつか集められたものを、パターンカタログといいます。

 デザインパターンとは、オブジェクト指向でのソフトウェアの設計に焦点をあてたパターンカタログです。
別名、GoFパターンと言われます。
GoFとは、Gang of Four(4人のギャング)の略で、このカタログをまとめあげた4人のグル(導師)を指します。

 デザインパターンには23ものパターンがカタログされています。
これらすべてについてお話しするのには、けっこうな時間がかかりそうですね。
できるだけ、使う機会が多そうなパターンからお話ししていきたいと思います。

 で、今回は最初のパターン、Composite(コンポジット)パターンです。

コンテンツ

  1. コンポジット
  2. 部署のコンポジット
  3. 人体のコンポジット
  4. 計画のコンポジット
  5. コンポジットは使えます
  6. オススメ

コンポジット

 コンポジットパターンは、普段の私たちの物事の捉え方に非常にマッチしたパターンです。
ですから、比較的理解しやすいパターンと言えます。
コンポジット(Composite)とは、合成物複合物という意味です。

 ソフトウェアというのは、人間がすること(あるいは、するはずのこと)をコンピュータに肩代わりさせるためのものです。
人間がすることの内容を細かく分析して、そのやり方をコンピュータに教える過程が、ソフトウェア開発なのです。
ですから、人間の普段の物事の捉え方が、ソフトウェア開発には大きく影響しています。
コンポジットパターンは、日常に多く存在するパターンであると共に、ソフトウェア開発にも非常に頻繁に使用できるパターンでもあるのです。

部署のコンポジット

 会社の「部署」を思い出してください。
「部署」というものには、事業部、部、課など、大きなものから小さなものまでいろいろありますね。
この事業部、部、課というのは、大きさのレベルの名前ですね。
一番大きな事業部というレベル。
次に大きな部というレベル。
一番小さな課というレベル。

 さて、普通、事業部はいくつかの部を含み、部はそれぞれいくつかの課を含んでいますよね。
事業部も部も課も、全部「部署」の一種なわけですから、これはつまり部署が部署を含んでいるわけです。
はい、これがコンポジットパターンです。

 部署というのは、実は抽象クラスです。
〜部とかいう部署はあっても、〜部署という部署はありませんよね。
部署というのは、実際には存在しない、抽象的な概念なわけです。
部署という抽象クラス特化して、事業部や部や課という具象クラスができています。
で、第一事業部とか、開発部とか、営業担当課とかいうのが、そのインスタンスなわけです。

 部署という抽象クラスが、「いくつかの部署」という属性をもっているわけですね。
部署の全てのサブクラスは、この属性を継承します。
ですから、事業部が部を含むことも、部が課を含むことも、これだけで説明できるわけです。

 部署は、事業部や部のように他の部署を含む場合と、課のように他の部署を含まない場合があります。
また、全ての部署は、「命令を遂行する」という同じ振る舞いを持っています。
他の部署を含んでいる部署の場合、この振る舞いの内容は、自分が含んでいる部署に命令を伝達することです。
単に命令を伝達するだけでなく、自分の部署でやるべき作業は自分で行い、特定の作業は下位の部署に任せるというカンジで、役割分担する場合もありますね。
他の部署を含んでいない部署の場合は、自分自身で命令を遂行します。

 こうみると、会社全体がツリー構造になっていることがおわかりだとおもいます。
ツリー(tree)構造とは、木が幹から枝、葉と段々枝分かれしているのと同じように、枝分かれを繰り返していく構造です。
そして、「課」が末端ですね。
このような末端のオブジェクトを、葉(Leaf)といいます。

 人間は、組織構造を作るとき、たいていツリー構造にしたがります。
上の説明のように、トップダウンの情報伝達がしやすいからです。
また、こういう構造なら、新しい部署を付け加えたり、今ある部署を削除したりも比較的簡単です。
事業部、部、課と、好きな大きさで追加、削除ができますからね。

人体のコンポジット

 組織以外にも、なにかの構造を把握しようとするときには、やはりツリー構造で把握しようとすることが多いものです。

 たとえば、人体の構造。
体を、五体というように各部に分けて考えますよね。
さらに、腕なら上腕、肘、下腕、手に分けられます。
手は手のひらと手の甲、五指に分けられます。
このように、人間は何かの構造を把握しようとするとき、まずそれをいくつかの部分に分け、各部分をさらに分け、さらに…。
というふうに、「区分け」というテクニックをよく使います。
この区分けの結果できるのが、コンポジット構造なのです。

 このようなコンポジット構造は、もともとひとつのものが区分けされてできたものですので、たいてい共通する抽象概念を持っています。
最初の「部署」を思い出してください。
次の体の各部の例については?
の各部っていうくらいなんだから、「体」が抽象概念ですね。

計画のコンポジット

 ああ、そうだ。
もうひとつ例を挙げておきましょう。
「計画」です。
計画というのは、単純な作業のシーケンス(手順、並び)ではないんです。
とくに、仕事上で作る計画というのは、まったくシーケンスではありませんよね。

 計画には大まかな計画と、詳細な計画がありますね。
大まかな計画に含まれるひとつひとつの作業について、それぞれ詳細な計画を立てるわけです。
大まかな計画でのひとつの作業のゴールが、詳細な計画では全体のゴールになります。

 ここで、「計画」という抽象クラスは「目標を達成する」という振る舞いを持ってるわけですよね。
大まかな計画は、「目標を達成する」ためにいくつかの詳細な計画を含んでいます。
詳細な計画は、大きな目標を達成するための一歩一歩の到達点としての小さな目標を、大まかな計画から受け継ぎます。
詳細な計画にとっては、その一歩の「目標を達成する」ことが目的なわけです。

このように、カタチのあるものでもないものでも、コンポジット構造を持ちうるのです。

コンポジットは使えます

 コンポジットパターンを使って、あなたの周りのいろんなものの構造を把握してみてください。
今までとは違った、問題の分析ができるのではないでしょうか。

 コンポジットパターンは、単に物事の構造を把握することができるだけではありません。
部署の例でお話ししたように、構造の追加や削除など、構造を操作することが簡単にできるようになります。
(体の構造等、追加や削除などありえない物事もありますので、まぁそういうのは別ですがね)
また、イテレータ(Iterator)パターン、ビジタ(Visitor)パターン、デコレータ(Decorator)パターン等、他の様々なパターンと組み合わせることで、さらに高度なやり方で構造を調べたり操作したりすることができるようになります。
コンポジットパターンは、そういった他のパターンを効果的に適用するための土台にもなるわけです。

オススメ

 ソフトウェア開発者の方には、オブジェクト指向における再利用のためのデザインパターン
デザインパターンのバイブルです。
冒頭でお話ししたように、デザインパターンとは一般にGoFパターンのことを言います。
この本こそが、まさにそのGoFが著した、GoFパターンの本です。
ですので、デザインパターンを学ぶのであれば、ぜひこの本を読んでいただきたいと思います。

 今回お話ししたコンポジットパターンやイテレータ、ビジタ、デコレータパターンはもちろん、23のデザインパターン全てについて、GoF自身がまとめた、本来のアイデアを知ることができます。

 もちろん、私もこの本でデザインパターンを学びました。
 Java言語でのデザインパターンについては、Java言語で学ぶデザインパターン入門をご覧ください。

 Javaを使って、デザインパターンがわかりやすく解説されていますので、Javaがメインの方なら、わかりやすいのではないでしょうか。

 Java以外でも、いろいろな言語を得意とする開発者の方向けに、それぞれの言語で解説されたデザインパターンの本があります。
オブジェクト指向における再利用のためのデザインパターンは、サンプルがSmalltalkで書かれていますので、わかりにくいと感じた方は、ご自分が得意な言語の本も読んでみるといいでしょう。


 今回ご紹介したコンポジットパターンは、私がはじめて設計に適用したパターンでもあります。
正直言って、今となっては、それが最適解であったとは言いがたいものがあります。
でも、その当時の私のスキルでは、これがせいいっぱいでした。
単純な話、そのとき私が一番理解しやすかったというのが、適用の理由です。
もうひとつ、既に述べたように、適用範囲が広くて、適用しやすかったというのも大きな理由でしょう。

 デザインパターンを全て学んで、確実に使いこなせるようになってから適用するというのが理想かもしれませんが、私は逆をお勧めします。
何か一つでも二つでも学んで、それが適用できそうなところを見つけたら、すぐに適用してみてください。
それが最適解でなかったとしても、私は問題ないと思います。
チームにあなたよりデザインパターンをよく理解している人がいる場合
あなたの間違いを指摘し、ベターな設計を示してくれるでしょう。
あなたは、その指摘から学ぶことができます。
また、ベターな設計と自分の設計を比較することからも、多くを学べるはずです。
チームにあなたほどデザインパターンを理解している人がいない場合
今のあなたのチームのスキルでは、あなたの設計が最もベターなわけです。
結局、あなたのチームは今持てるスキルの中で、せいいっぱい良い設計を作るしかないんです。
あなたがせいいっぱいの力でパターンを適用して作った設計がそれです。
自信を持ってGoです。
 ただ、ひとつ気をつけておいていただきたいのはデザインパターンもまた銀の弾丸ではないということです。
もし、パターンを適用するデメリットが、メリットを少しでも超えていることを発見したなら、そしていくらか手を加えてもそれが覆せる見込みがないのなら、そのパターンからはすぐに手を引いてください。
他にベターなパターンが見つけられなければ、パターンを適用する必要はありません。

 ひょっとしたら、あなたのスキルがもう少しだけ高ければ、パターンをもっとうまく適用できたかもしれませんね。
でも、今はそれでいいのです。
自分のスキル、そしてチームのスキルを、見誤らず公平に判断してください。
「背伸び」とか「ムリに」とかいうのは、全くいいことではありません。

手の内にあるコマの中で、最良のことをすべきです。
そして、次からはもっといいやり方ができるように、スキルを高めていきましょう。
posted by craftsman at 17:00 | 東京 🌁 | Comment(0) | TrackBack(0) | デザインパターン
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント: [必須入力]

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


※画像の中の文字を半角で入力してください。
この記事へのトラックバックURL
http://blog.seesaa.jp/tb/47880389
※言及リンクのないトラックバックは受信されません。

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

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