Compositeパターン

概要

ツリー構造(深さは均一じゃなくていい)で表現できるオブジェクトを扱うためのパターン

ディレクトリとファイルなど再帰的に表現できるものに使う。

共通のインターフェースを用意して、ツリーの親が子の計算を集計するという処理を再帰的に行う。

使い方

カテゴリーと商品(カテゴリーはネストする)で表現する

// 共通のインターフェース
trait CategoryItem {
  fn get_price(&self) -> u32;
}

// CategoryはCategoryItemを複数持つ
struct Category {
  name: String,
  items: Vec<Box<dyn CategoryItem>>,
}
// Categoryに対してCategoryItemを実装
impl CategoryItem for Category {
  fn get_price(&self) -> u32 {
    self.items.iter().map(|item| item.get_price()).sum()
  }
}

// Productは末端なのでそのまま
struct Product {
  name: String,
  price: u32,
}
impl CategoryItem for Product {
  fn get_price(&self) -> u32 {
    self.price
  }
}

こうすることで

category1.get_price() // category1の子の合計金額を返す

とすると再帰的に計算されてそのcategory以下のすべての商品の合計金額が返ってくる。

使い所

ネストする形のオブジェクト(モデルなど)を定義した時とかに使える。

参考