Interface-delegatie met de operator by stelt een klasse in staat om alle aanroepen van een interface naar een bepaalde delegaatobject te leiden. Dit vermindert code duplicatie en realiseert het compositiepatroon.
Voorbeeld:
interface Logger { fun log(message: String) } class ConsoleLogger: Logger { override fun log(message: String) = println("LOG: $message") } class Service(logger: Logger): Logger by logger { fun doWork() { log("Service is working") } } val service = Service(ConsoleLogger()) service.doWork() // LOG: Service is working
Verschillen met eigenschapsdelegatie:
val/var x by ...) wordt toegepast op een specifieke eigenschap en vereist implementatie van de delegaatinterface (bijvoorbeeld ReadWriteProperty).Voordelen:
Nadelen:
Wat is het verschil tussen interface-delegatie (
by) en interface-implementatie met een object dat via een veld wordt doorgegeven?
Antwoord:
Delegatie (via by) implementeert automatisch alle methoden van de interface via het delegaatobject. Als je echter gewoon het delegaatobject als een veld bewaart en zijn methoden handmatig aanroept, moet je elke methode van de interface handmatig definiëren — wat leidt tot duplicatie en fouten. Bovendien biedt delegatie via by meer leesbaarheid en minder boilerplate-code:
// Zonder delegatie class Service2(private val logger: Logger): Logger { override fun log(message: String) = logger.log(message) }
Verhaal
In een project probeerden ze het decoratorpatroon voor de Logger-interface handmatig te implementeren, vergat een aanvullende methode van de interface te implementeren die later aan Logger werd toegevoegd. Het project compileerde, maar de nieuwe functionaliteit werkte niet, omdat de implementatie een "lege" was. Interface-delegatie via by zou deze fout hebben voorkomen: alle nieuwe methoden worden automatisch door de delegaat geïmplementeerd.
Verhaal
Bij interface-delegatie via by, overschreef de ontwikkelaar een van de methoden van de interface, maar vergat dat de andere methoden nog steeds via de delegaat gaan. Als gevolg hiervan werkte een deel van de functionaliteit "niet-standaard" — de fout werd een lange tijd niet opgemerkt in de logica van bedrijfsdoelen.
Verhaal
Ze probeerden delegatie van meerdere interfaces met overlappende methoden via by te implementeren, wat leidde tot een conflict — de compiler gaf een ambiguïteitsfout, en ze moesten de overlappende methoden expliciet overschrijven, anders compileerde het project niet.