package pattern class Activity(val name : String) { protected var nested : List[Activity] = Nil var parent : Option[Activity] = None def subActivities = nested.reverse def level : Int = { var i = 0 for (p <- parent) { i = p.level + 1 } i } override def toString = { var prefix = " " for (i <- 0 to level) { prefix = prefix + " " } val nestedString = subActivities.foldLeft("") {_+_.toString} prefix + name + "\n" + nestedString } } class CompositeActivity(name : String) extends Activity(name) { def add[B <: Activity](a : B) = { nested = a :: nested a.parent = Some(this) a } } class ProjectPlan(name : String) extends CompositeActivity(name) class SummaryTask(name : String) extends CompositeActivity(name) class Task(name : String) extends Activity(name) object Composite { def main(args : Array[String]) { val plan = new ProjectPlan("MyGreatPlan") val s = plan.add (new SummaryTask("Get it all together")) s.add (new Task("Put the kettle on")) s.add (new Task("Relax with a cuppa")) s.add (new Task("Now think ...")) println(plan) } }