Composite パターンを考えます。

デザインパターンを調べ始めた経緯はこちらです。

他のパターンはこちらです。

今回もこちらの本を読み解いていきます。

オブジェクト指向における再利用のためのデザインパターン

また読み解く上で日本語の専門用語より英語の方がすんなりと受け入れられることが多いので英語の原文としては下記を参照しております。

本での引用箇所はこのような四角で囲う

もしくは「このような鉤括弧」で囲います。

それ以外の引用に関しては四角・鉤括弧のすぐ下にURLなどのソースを明記しています。


Composite とは日本語に直すとどのような意味になるのでしょうか?

色々調べてみたのですが直感的にこのパターンを表しそうな単語はなかったので訳は書かないことにしました。

本でのカタログにあるComposite パターンは、パターンの目的から始まります。そして、パターンを適用する動機として仮の問題を想定し、その解決策がComposite パターンであることを示します。

その後、適用可能性・構造・結果・実装・サンプルコード・関連するパターンと内容が続きます。今回は「結果」までを考えていきます。

※かなり紆余曲折することや誤った解釈をする可能性があります。その際は是非コメントをお待ちしています。よろしくお願いします。

※本の項目通りに進めずにComposite パターンを自身が理解した過程で再構成しています。

でははじめます。


Composite パターンの目的

部分ー全体構造を表現するために、オブジェクトを木構造に組み立てる。Composite パターンにより、クライアントは、個々のオブジェクトを合成したものを一様に扱うことができるようになる。

部分ー全体構造は英語で「part-whole hierarchies」です。
かなり調べたのですが詳細がなかったのでシンプルに『部分から全体にかけた階層状の表現のこと』と解釈しました。(コメントお待ちしています。。)

木構造は

In computer science, a tree is a widely used abstract data type that simulates a hierarchical tree structure, with a root value and subtrees of children with a parent node, represented as a set of linked nodes.

コンピュータサイエンスの分野では、ツリーは広く使われている抽象データ型で、ルート値と親ノードを持つ子のサブツリーを持つ階層的な木構造をシミュレートし、リンクされたノードのセットとして表現されます。

画像1

上記図のようなイメージの構造だと解釈しました。

最後の一文に関しては次の構造に関連するので次に進もうと思います。

Composite パターンの構造

画像2

http://www.cs.unc.edu/~stotts/GOF/hires/pat4cfso.htm

Composite パターンによる典型的なオブジェクトの構造は次のようになる。

画像3

http://www.cs.unc.edu/~stotts/GOF/hires/pat4cfso.htm

「Composite パターンによる典型的なオブジェクトの構造」の図になるようにクラスが構成されています。

Component クラス
・「Composite 内のオブジェクト(Componentと呼ぶ)のインタフェースを宣言する。」
・必要に応じて、すべてのクラスに共通するインタフェースのデフォルトの動作を実装する。
・「子にあたるComponent オブジェクトにアクセスしたり、それを管理するためのインタフェースを宣言する。」
・(オプション)再帰的な構造の中でComponentの親にアクセスするためのインタフェースを定義し、必要に応じてそれを実装します。

Leaf クラス
・「Composite内の末端のオブジェクト(leafと呼ぶ)を表」します。末端なのでleafオブジェクトが子を持つことはありません。
・Composite内のプリミティブなオブジェクトの動作を定義します。

Composite クラス
・子を持ったComponentのための動作を定義します。
・子のComponentを格納します。
・Componentクラスのインタフェースで子関連の操作を実装します。

Client クラス
・Component インタフェースを通じて、Composite内のオブジェクトを操作します。

Composite パターンの特徴

1. プリミティブオブジェクト(leaf)とCompositeオブジェクトで構成されるクラス階層を定義します。
プリミティブオブジェクトは、より複雑なオブジェクトに構成することができ、さらにそのオブジェクトは、再帰的に構成することができます。クライアントのコードがプリミティブオブジェクトを要求する場合は常に、Compositeオブジェクトを要求することもできます。

2. クライアントをわかりやすくします。
クライアントはComposite構造と個々のオブジェクトを同じように扱うことができます。クライアントは通常、自分が扱っているのがleafなのかCompositeなのかを知りません(気にするべきではありません)。これにより、クライアントのコードが単純化されます。というのも、Compositeを定義しているクラスに対して、タグやケースを指定するスタイルの関数を書かなくて済むからです。

3. 新しい種類のコンポーネントの追加が容易になります。
新しく定義された Composite や leaf のサブクラスは、既存の構造やクライアントコードと自動的に連携します。新しいComponentクラスのためにクライアントを変更する必要はありません。

4. デザインが過度に一般的になる可能性があります。
新しいComponentを簡単に追加できるようにすると、CompositeのComponentを制限するのが難しくなるというデメリットがあります。
例としてはCompositeに特定のComponentだけを持たせたい場合が当たります。
Compositeでは、型チェックシステムで制約を適用することはできません。代わりに、ランタイムチェック(実行時チェック)を使用する必要があります。

Composite パターンの有効な条件

Composite パターンは次のような条件において有効に使うことができます。

・オブジェクトを部分から全体にかけた階層状に表現したい場合。

・クライアントがオブジェクトのcompositionと個々のオブジェクトの違いを無視できるようにしたい場合で、「クライアントは、Composite構造内のすべてのオブジェクトを一様に扱うことができ」ます。

画像4


今回は聞き慣れない単語でかつ調べてもピンと来なかったのでかなり大変でした。参考サイトでSwiftでのComposite パターンがありPlayGroundsなどで実行しながら理解を深めました。実装に関しても記事にできたらと考えています。

最後自分の理解で用意したcompsiteとcompositionのイメージがありますがもし違う解釈でしたらコメントいただけると大変助かります。。

最後までお読みいただきありがとうございます。


参考サイト


この記事が気に入ったらサポートをしてみませんか?