ProgrammingBackend Developer

What is the delegation pattern in Kotlin and how to implement behavior delegation between objects using the language?

Pass interviews with Hintsage AI assistant

Answer

Background:

The "Delegation" pattern is known in many OOP languages, it is the principle of passing work from one object to another. In Java, delegation is implemented manually — through an internal field and proxying methods. In Kotlin, delegation is brought to the syntax level using the by keyword.

Problem:

Implementing the delegation pattern in Java leads to "God" proxy classes that are overloaded with boilerplate code and incur high maintenance costs for the interface. It is challenging to maintain interface contract updates and change delegates.

Solution:

Kotlin allows you to create classes that implement an interface not directly, but by delegating all of its methods to another object using the notation class Foo(...) : MyInterface by delegateObj. This allows for writing concise and understandable code, eliminating boilerplate without losing flexibility.

Code example:

interface Base { fun print() } class BaseImpl(val x: Int) : Base { override fun print() = println(x) } class Derived(b: Base) : Base by b fun main() { Derived(BaseImpl(42)).print() // 42 }

Key features:

  • Declarative delegation of interface methods
  • Reduction of boilerplate code
  • Flexible modification of delegation logic and implementation replacement

Tricky questions.

Can a declaring class change the behavior of a specific method despite delegation?

Yes — if the interface method is implemented explicitly in the delegating class (Derived), it will "override" the delegated behavior for that specific method.

Example:

class Derived(b: Base) : Base by b { override fun print() = println("Overrided!") }

Is it possible to delegate multiple interfaces to different objects at once?

No, in Kotlin, you cannot directly delegate multiple different interfaces to different objects in one declaration. You would need to write a class with manual delegation or combine inheritance and delegation, if the architecture allows it.

Does delegation work with abstract classes or only with interfaces?

Delegation is only possible with interfaces, not with abstract classes — because abstract classes can have states and protected methods that are incompatible with delegation declaration using by.

Common mistakes and anti-patterns

  • The desire to use delegation for abstract classes (the compiler will not allow)
  • Attempts to do multiple delegation through one class
  • Neglecting extensibility in complex production code

Real-world example

Negative case

A developer manually implements the delegation pattern for a dozen methods of a large interface. When extending the interface, they forget to add new proxy methods. The code grows, and bugs multiply.

Pros:

  • Clear control over each delegation logic

Cons:

  • Class overload
  • High maintenance costs

Positive case

The by syntax is used for automatic interface delegation. Easy to change implementations and swap delegates on the fly without risking errors during contract maintenance.

Pros:

  • Fast implementation and delegate changes
  • Less code, fewer bugs

Cons:

  • Limitation to interfaces only
  • Possible non-obvious consequences when overriding a method in the delegating class