Die Delegierung einer Schnittstelle mit dem Operator by ermöglicht es einer Klasse, alle Aufrufe der Schnittstelle an ein bestimmtes Delegatobjekt weiterzuleiten. Dies reduziert den Code-Duplizierung und implementiert das Kompositionsmuster.
Beispiel:
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
Unterschiede zur Delegierung von Eigenschaften:
val/var x by ...) wird auf eine bestimmte Eigenschaft angewendet und erfordert die Implementierung der Delegatschnittstelle (zum Beispiel ReadWriteProperty).Vorteile:
Nachteile:
Was unterscheidet die Delegierung einer Schnittstelle (
by) von der Implementierung der Schnittstelle durch Übertragung eines Objekts über ein Feld?
Antwort:
Die Delegierung (über by) implementiert automatisch alle Methoden der Schnittstelle über das Delegatobjekt. Wenn man jedoch das Delegatobjekt einfach als Feld speichert und seine Methoden manuell aufruft, muss man jede Methode der Schnittstelle manuell implementieren – das führt zu Duplizierung und Fehlern. Darüber hinaus bietet die Delegierung über by mehr Lesbarkeit und weniger Boilerplate-Code:
// Ohne Delegierung class Service2(private val logger: Logger): Logger { override fun log(message: String) = logger.log(message) }
Geschichte
Im Projekt wurde versucht, das Dekorator-Muster für die Schnittstelle Logger manuell zu implementieren, dabei wurde vergessen, eine zusätzliche Methode der Schnittstelle zu implementieren, die später in Logger hinzugefügt wurde. Das Projekt wurde kompiliert, aber die neue Funktionalität funktionierte nicht, da die Implementierung "leere" war. Die Delegierung der Schnittstelle über by hätte diesen Fehler vermeiden können: Alle neuen Methoden werden automatisch vom Delegaten implementiert.
Geschichte
Bei der Delegierung einer Schnittstelle über by hat der Entwickler eine der Methoden der Schnittstelle überschrieben, aber vergessen, dass die anderen Methoden immer noch über das Delegat weitergehen. Infolgedessen funktionierte ein Teil der Funktionalität "nicht standardmäßig" — der Fehler wurde in der Logik der Geschäfts-methoden lange nicht gefunden.
Geschichte
Es wurde versucht, die Delegierung mehrerer Schnittstellen mit sich überschneidenden Methoden über by zu implementieren, es kam zu einem Konflikt — der Compiler gab einen Mehrdeutigkeitsfehler aus, es war notwendig, die sich überschneidenden Methoden explizit zu überschreiben, andernfalls wurde das Projekt nicht kompiliert.