GoFのデザインパターンのコンポジット(Composite)のRubyコードを使った紹介記事です。
🍮 コンポジットとは?
「全体〜部分」(個別のオブジェクトと合成したオブジェクト)を同一のものとしてとらえることで、再帰的な構造をクラスで表現することをCompositeデザインパターンと呼びます。「全体〜部分」は同じインタフェースを継承します。
コンポジットは次の3つの要素によって構成されます。
- コンポーネント(Component):すべてのオブジェクトの基底となるクラス
- リーフ(Leaf):プロセスの単純な構成要素、再帰しない
- コンポジット(Composite):コンポーネントのひとつでサブコンポーネントを構成
例としては、ディレクトリとフォルダを同様のコンポーネントとして扱うことで、削除処理などを再帰的に行えるようにできることが挙げられます。ちなみに「再帰」とは、ある処理の中で再びその手続きを呼び出すことです。
🐠 コンポジットのメリット
- ファイルシステムなどの木構造を伴う再帰的なデータ構造を表現できる
- 階層構造で表現されるオブジェクトの取扱いを楽にする
🐝 ソースコード
ここではファイルシステムのモデルを使ってCompositeデザインパターンを説明します。
FileEntryクラス(Leaf)
:ファイルを表すDirEntryクラス(Composite)
:ディレクトリを表すEntryクラス(Component)
:FileEntry, DirEntryクラスの共通メソッドを規定
まずFileEntry
クラス, DirEntry
クラスの共通メソッドを規定するEntry
クラスです。
Componentにあたります。メソッドの実装はFileEntry/DirEntryクラスが個別に持っています。
# FileEntry, DirEntryクラスの共通メソッドを規定(Component) |
次にファイルを表すFileEntry
クラスです。ファイルはその下にファイルをもつことができない、つまり再帰できないのでCompositeデザインパターンのLeafにあたります。
# Leaf (中身) |
最後がディレクトリを表すDirEntry
クラスです。ディレクトリはその下にファイルをもつことができる、つまり再帰できるのでCompositeデザインパターンのCompositeにあたります。このクラスは独自のクラスとして、ファイルを追加する#add
メソッドを持っています。
# Composite |
コーディングは以上です。結果を確認します。
root = DirEntry.new("root") |
ディレクトリの中にディレクトリ/ファイルを追加できて、#ls_entry
メソッド、#remove
メソッドで同一のものとみなして処理できていることがわかります。(再帰的にメソッドを呼び出せていることがわかります)
🐰 コンポジットパターンの注意点
コンポジットパターンでは、コンポジット(Composite)が任意の深さのツリーを作れるようにしておくことが重要となります。