Designing with Delegates
We'll cover the following...
In the previous chapter, you saw that Kotlin offers a different and safer way to use inheritance than Java. Likewise, Kotlin has much better support than Java for delegation. Before we dive into the syntax for delegation, we’ll take a small problem and design it using inheritance, to better understand the reasons to use delegation over inheritance. Soon we’ll run into issues where inheritance begins to become a hindrance, and you’ll see how delegation may be a better choice for the problem. We’ll then look at how Kotlin is able to readily support our new design using delegation, without flinching.
A design problem
Imagine an application that simulates the execution of software projects by corporate teams (don’t worry, we’ll limit the scope so our program, unlike some enterprise projects, actually completes). We need workers to get real stuff done—let’s start with a Worker interface:
// version1/project.kts
interface Worker {
fun work()
fun takeVacation()
}
A worker may perform two tasks: does work and occasionally takes vacation. Let’s implement two classes, JavaProgrammer
and CSharpProgrammer
, that specialize in two different languages—the idea of being polyglot has not caught this company’s attention yet.
class JavaProgrammer : Worker {override fun work() = println("...write Java...")override fun takeVacation() = println("...code at the beach...")}class CSharpProgrammer : Worker {override fun work() = println("...write C#...")override fun takeVacation() = println("...branch at the ranch...")}
The programmers perform their work()
based on their language specialty and enjoy their vacations according to the established industry standards.
The company wants to have a software development manager for their teams—let’s write that class:
// version1/project.kts
class Manager
The Manager
class is very small, agile, and highly efficient, and as you’d expect, does nothing. A call to work()
on an instance of this manager won’t lead any- where. We need to design some logic into the Manager
, but that’s not easy.
The inheritance misroute
Now that we have the interface Worker and the two implementations, JavaProgrammer
and CSharpProgrammer
, let’s focus on using them with the Manager
class. The company will want to rely on the Manager
to execute and deliver the project. The Manager
, in turn, will need a programmer to get the actual work done. In the most simple form, a call to ...