Solution (source code)

= Solution

Add one concrete decorator and a small application:

``
class Sports(account: CableTV) extends Packages(account) {
  override def cost: Double = super.cost + 5.0
  override def packages: String = super.packages + ", Sports"
}

object CableTVExample extends App {
  val basic: CableTV = new BasicPlan
  val movies: CableTV = new Movies(basic)
  val hd: CableTV = new HDChannels(movies)
  val sports: CableTV = new Sports(hd)
  Seq(basic, movies, hd, sports).foreach { account =>
    println(account.packages + " = £" + account.cost)
  }
}
``

The output is:

``
Basic plan = £30.0
Basic plan, Movies = £40.0
Basic plan, Movies, HD channels = £47.0
Basic plan, Movies, HD channels, Sports = £52.0
``

The final price is \b[£52]. Each new wrapper leaves earlier account objects available at their original prices. In the <UML> <class diagram>, both `BasicPlan` and `Packages` realize `CableTV`; each package class inherits `Packages`. The `account` relationship points from the decorator to another `CableTV` component. It is an association, without asserting exclusive lifetime ownership.

\Image[/past-exam-of-the-year-1-of-the-computer-science-course-of-the-university-of-oxford/2017/imperative-cable-tv-decorator.png]
{title=Cable TV decorator classes extended with the Sports package}
{description=Original UML class diagram. Dashed hollow-triangle arrows denote interface realization; solid hollow-triangle arrows denote class inheritance. The account association permits nested decorators.}