= 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.}
Back to article page