Composite (Design Pattern)


The composite design pattern allows you to interact with individual objects and compositions of objects in the same way. Oftentimes, this pattern aggregates several implementations of an interface into a single, combined implementation. For example:

interface BillableItem {
  fun showPrice()
}

class Burger : BillableItem {
  override fun showPrice() = 
    println("Burger: £3.50")
}

class Fries : BillableItem {
  override fun showPrice() = 
    println("Fries: £1.50")
}

class Milkshake : BillableItem {
  override fun showPrice() = 
    println("Milkshake: £2.20")
}

class Meal(
  private vararg val items: BillableItem
) : BillableItem {
  override fun showPrice() = 
    items.forEach(BillableItem::showPrice)
}

The Meal class is an example of the composite pattern as its API hides the detail of whether the class represents a single part of a hierarchy objects, or the entire tree.