La délégation d'une interface à l'aide de l'opérateur by permet à une classe de rediriger tous les appels d'interface vers un objet délégué spécifique. Cela réduit la duplication de code et implémente le modèle de composition.
Exemple :
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
Différences par rapport à la délégation de propriété :
val/var x by ...) s'applique à une propriété spécifique et nécessite l'implémentation de l'interface du délégué (par exemple, ReadWriteProperty).Avantages :
Inconvénients :
En quoi la délégation d'interface (
by) diffère-t-elle de l'implémentation d'une interface en passant un objet via un champ ?
Réponse :
La délégation (via by) implémente automatiquement toutes les méthodes de l'interface via l'objet délégué. Si l'on stocke simplement l'objet délégué en tant que champ et appelle ses méthodes manuellement, il est nécessaire d'écrire chaque méthode de l'interface manuellement - ce qui entraîne de la duplication et des erreurs. De plus, la délégation via by offre une meilleure lisibilité et moins de code boilerplate :
// Sans délégation class Service2(private val logger: Logger): Logger { override fun log(message: String) = logger.log(message) }
Histoire
Dans un projet, ils ont essayé d'implémenter le modèle de décorateur pour l'interface Logger à la main, oubliant d'implémenter une méthode supplémentaire de l'interface qui a été ajoutée plus tard à Logger. Le projet se compilait, mais la nouvelle fonctionnalité ne fonctionnait pas car l'implémentation était "vide". La délégation d'interface via by aurait permis d'éviter cette erreur : tous les nouveaux méthodes sont automatiquement implémentées par le délégué.
Histoire
Lors de la délégation d'interface via by, le développeur a redéfini l'une des méthodes de l'interface, mais a oublié que les autres méthodes passent toujours par le délégué. En conséquence, une partie de la fonctionnalité fonctionnait de manière "non standard" - l'erreur n'a pas été détectée pendant longtemps dans la logique des méthodes métier.
Histoire
Ils ont essayé de mettre en œuvre la délégation de plusieurs interfaces avec des méthodes se chevauchant via by, un conflit est survenu - le compilateur a commencé à générer une erreur d'ambiguïté, et il a été nécessaire de redéfinir explicitement les méthodes dupliquées, sinon le projet ne se compilait pas.