...

/

Designing with Delegates

Designing with Delegates

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.

Press + to interact
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 ...