ProgrammationDéveloppeur Backend

Qu'est-ce que le modèle de délégation en Kotlin et comment réaliser la délégation de comportement entre les objets à l'aide du langage ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse

Historique de la question :

Le modèle de "Délégation" est connu de nombreux langages de programmation orientés objet, c'est le principe selon lequel un objet délègue du travail à un autre objet. En Java, la délégation est mise en œuvre manuellement — via un champ interne et le proxy des méthodes. En Kotlin, la délégation est intégrée au niveau de la syntaxe grâce au mot clé by.

Problème :

La mise en œuvre du modèle de délégation en Java conduit à des classes proxy "divines", surchargées de code générique et à des efforts considérables pour maintenir l'interface. Il est difficile de maintenir la mise à jour des contrats d'interface et de modifier les délégués.

Solution :

Kotlin permet de créer des classes qui implémentent une interface non pas directement, mais en déléguant toutes ses méthodes à un autre objet via l'instruction class Foo(...) : MyInterface by delegateObj. Cela permet d'écrire du code concis et clair, éliminant la routine sans perdre de flexibilité.

Exemple de code :

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 }

Critères clés :

  • Délégation déclarative des méthodes d'interface
  • Réduction du code générique
  • Modification flexible de la logique de délégation et substitution de l'implémentation

Questions pièges.

Un classe déclarante peut-elle modifier le comportement d'une méthode particulière, malgré la délégation ?

Oui — Si la méthode de l'interface est implémentée explicitement dans la classe déléguée (Derived), elle "surlèvera" le comportement délégué pour cette méthode particulière.

Exemple :

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

Peut-on déléguer plusieurs interfaces à différents objets ?

Non, en Kotlin, on ne peut pas déléguer plusieurs interfaces différentes à différents objets dans une seule déclaration. Il faudra écrire une classe avec une délégation manuelle ou combiner héritage et délégation, si l'architecture le permet.

La délégation fonctionne-t-elle avec des classes abstraites ou uniquement avec des interfaces ?

On peut seulement déléguer des interfaces, pas des classes abstraites — car les classes abstraites peuvent avoir des états et des méthodes protégées, incompatibles avec la déclaration de délégation via by.

Erreurs typiques et anti-modèles

  • Vouloir utiliser la délégation pour des classes abstraites (le compilateur ne le permettra pas)
  • Essayer de faire une délégation multiple via une seule classe
  • Ignorer l'extensibilité dans du code de production complexe

Exemple de la vie courante

Cas négatif

Un développeur implémente manuellement le modèle de délégation pour une dizaine de méthodes d'une grande interface. À chaque fois que l'interface est étendue, il oublie d'ajouter de nouvelles méthodes-proxys. Le code grossit, les bugs se multiplient.

Avantages :

  • Contrôle clair sur chaque logique de délégation

Inconvénients :

  • Surcharge de la classe
  • Le support coûte cher

Cas positif

La syntaxe by est utilisée pour la délégation automatique de l'interface. Il est facile de changer l'implémentation et de substituer le délégué en temps réel, sans trop de risques d'erreur lors de la maintenance du contrat.

Avantages :

  • Intégration rapide et changement de délégué
  • Moins de code, moins de bugs

Inconvénients :

  • Limitation uniquement aux interfaces
  • Possibilité de conséquences non évidentes lors de la surcharge d'une méthode dans la classe déléguée