デザインパターン-Composite

Compositeパターンとは

Compositeデザインパターンは、「全体-部分」のモデル(個別のオブジェクトと合成したオブジェクト)を同一視することで、再帰的な構造をクラスで表現するためのパターンです。

「Composite」は「合成物、複合物」という意味の英単語です。


「全体-部分」のモデルは、「容器-中身」の関係です。

例えば、ファイルシステムにおける「フォルダ」が「容器」であり、「ファイルやサブフォルダ」が「中身」を意味します。

同一視できるとは、対象となるオブジェクトが「容器」でも「中身」でも同じ様に取り扱える(同じ名前のメソッドで処理できる)ことを意味します。


Compositeパターンの利点

  • ファイルシステムなどの木構造を伴う再帰的なデータ構造を容易に表現することができます。
  • 階層構造で表現されるオブジェクトの取扱いを容易にします。

構成要素

  • Leaf(葉)
    • 「中身」を表すクラスです。
  • Composite(合成物)
    • 「容器」を表すクラスです。
    • 内部に複数の「Leaf」や「Composite」の保持が可能です。
    • 再帰処理を行います。
  • Component(部品)
    • 構成要素
    • 「Leaf」と「Composite」を同一視するため(同じメソッド名)のインタフェースを定義します。
  • ComponentAddException(追加例外)
    • 追加処理の例外を表します。

rubyによるCompositeパターンの実装


#!/usr/bin/env ruby

# Component(部品) 
class Entry
  def get_name
  end
  def ls_entry(prefix)
  end
end

# Leaf(葉) 
class FileEntry < Entry
  def initialize(name)
    @name = name
  end
  def get_name
    @name
  end
  def ls_entry(prefix)
    puts(prefix + "/" + get_name)
  end
end

# Composite(合成物) 
class DirEntry < Entry
  def initialize(name)
    @name = name
    @directory = Array.new
  end
  def get_name
    @name
  end
  def add(entry)
    @directory.push(entry)
  end
  def ls_entry(prefix)
    puts(prefix + "/" + get_name)
    @directory.each {|e|
      e.ls_entry(prefix + "/" + @name)
    }
  end
end

root = DirEntry.new("root")
tmp  = DirEntry.new("tmp")
tmp.add(FileEntry.new("passwd"))
tmp.add(FileEntry.new("plist"))
root.add(tmp)
root.ls_entry("")

関連ページ