La délegation dans kotlin


La délégation est un concept de la programmation orienté dans lequel vous transmettez la responsabilité d’une tache d’un objet à une autre objet ou à une autre méthode d’un objet.

L’objet à qui est attribué la responsabilité est appelé delegate(délégué).

Le délégation est une alternative à l’héritage et il existe plusieurs cas d’utilisation dans lesquels la délégation est privilégiée à l’héritage.

Vous devez privilégier la délégation à l’héritage lorsque vous souhaitez réduire le couplage entre les classes, l’impact de changement dans une classe etc.

La plupart des langages de programmation moderne tel que kotlin supporte nativement à la fois l’héritage et la délégation.

Table des matières

La délégation

Dans certains cas d’utilisation la délégation manuelle ou explicite qui consiste à assigner l’instance d’une classe à une autre classe peut être privilégié à l’héritage.

Il s’agit d’un concept dans lequel un objet A expose un certains nombre de ses comportements à l’extérieur mais en réalité délègue l’exécution de ses taches à un autre objet associé.

Nous allons d’abord voir un cas d’utilisation de l’héritage et ensuite comment vous pouvez implémenter la délégation.

Kotlin supporte nativement la délation.

Il existe en réalité deux types de délégation

  • La délégation explicite
  • La délégation implicite.

La délégation disponible dans kotlin est implicite.

Un exemple avec l’héritage

Supposons que vous souhaitez créer une classe pour représenter la liste des Etudiants d’une université.Nommons cette classe ListEtudiant. Une façon de créer cette classe est de faire dérivée la classe ListEtudiant de la classe ArrayList dont voici l’implémentation.

public class ListEtudiant<T> extends ArrayList<T> {
    public void push(T o) {
        add(o);
    }

    public T pop() {
        return remove(size() - 1);
    }
    public T shift(){
        return remove(0);
    }

    public boolean empty() {
        return size() == 0;
    }

  
}

Comme vous pouvez le constater la classe ListEtudiant fournit grâce à l’héritage sa propre implémentation de la classe ArrayList pour représenter la liste des étudiants et bénéficie ainsi de tous les méthodes de la classe ArrayList .La classe ListEtudiant possède alors toutes les méthodes de la classe ArrayList.

Délégation manuelle ou explicite

Au lieu d’utiliser l’héritage avec la classe ListEtudiant, vous pouvez par exemple utiliser la délégation pour gérer la liste des étudiants en passant comme argument un objet de la classe ArrayList au constructeur de la classe ListEtudiant ou bien à une méthode de la classe ListEdudiant. comme suit.

public class ListEtudiant<T>  {

    ArrayList<T>  list;
    public ListEtudiant(ArrayList<T> list){
    this.list=list;
    }
   
    public void push(T o) {
        list.add(o);
    }

    public T pop() {
        return list.remove(list.size() - 1);
    }
    public T shift(){
        return list.remove(0);
    }

    public boolean empty() {
        return list.size() == 0;
    }


}

Dans cet exemple la classe ListEdudiant possède une méthode pour chaque méthode de la classe ArrayList qu’elle souhaite gérer.Pour chaque méthode qu’elle fournit elle délègue en réalité l’exécution à une méthode de la classe ArrayList .

Vous devez constater qu’ aucune fonctionnalité du langage n’est utiliser pour implémenter la délégation explicite.Et vous devez donc vous même gérer le délégué pour écrire tous les appels des méthodes de la classe déléguée

Nous allons prendre un autre exemple avec une classe qui implémente une interface et qui est assigne à une autre classe comme délégué

fun main(){
  val myDelegate =MyDelegate();
  val derived = Derived(myDelegate)
    derived.work()
}


interface MyInterface{
    fun work()
}
class MyDelegate :MyInterface{
    override fun work() {
        println("Delegate push message")
    }
}
class Derived(myDelegate: MyDelegate){
    var delegate: MyDelegate =myDelegate

     fun work() {
        delegate.work()
    }
}

La délégation implicite

Le design pattern delegate est supporté nativement par kotlin à travers le mot clé by. Une classe dérivée peut accéder à toutes les méthodes publique implémentées d’une interface via un objet qui est le délégué.

C’est à dire qu’elle délègue l’implémentation de l’interface à un autre objet qui lui doit forcément implémenter l’interface

Voici un exemple

fun main(){
  val myDelegate =MyDelegate();
  val derived = Derived(myDelegate)
    derived.work()
}


interface MyInterface{
    fun work()
}
class MyDelegate :MyInterface{
    override fun work() {
        println("Delegate push message")
    }
}
class Derived(myDelegate: MyDelegate):MyInterface by myDelegate{

}

Résultat: Delegate push message

Comme vous devez le constater, avec la délégation implicite dans kotlin vous n’avez pas besoin de gérer le délégué.Dans cette exemple, lorsque vous appelez une méthode de l’objet derived le compilateur génère une méthode du même nom qui est implémentée par l’objet MyDelegate

Vous pouvez voir ça comme si lorsque vous appelez une une méthode de l’objet derived comme suit derived.work(), le compilateur appelle une méthode du même nom de l’objet MyDelegate

Redéfinir un membre d’une interface implémentée par délégation

Lorsque vous implémentez une méthode dans l’objet ,le compilateur utilisera la méthode que vous avez implémenter au lieu d’utiliser celle du délégué.

fun main(){
  val myDelegate =MyDelegate();
  val derived = Derived(myDelegate)
    derived.work()
}


interface MyInterface{
    fun work()
}
class MyDelegate :MyInterface{
    override fun work() {
        println("Delegate push message")
    }
}
class Derived(myDelegate: MyDelegate):MyInterface by myDelegate{
    override fun work() {
        print("Derived work")
    }
}

Résultat:Derived work

Notez que les membres redéfinis ne sont pas appelés par les membres de l’objet redéfini.L’objet délégué ne peut accéder qu’a l’implémentation de ces propres membres

fun main(){
  val myDelegate =MyDelegate();
  val derived = Derived(myDelegate)
   println(myDelegate.message)
   println(derived.message)
}


interface MyInterface{
    var message:String

}
class MyDelegate :MyInterface{
    override var message: String="Message du délégué"

}
class Derived(myDelegate: MyDelegate):MyInterface by myDelegate{
    override var message: String ="Message dérivée"

}

Résultat:
Message du délégué
Message dérivée

Conclusion

Voila, nous sommes à la fin de ce tutoriel sur la délégation dans kotlin. J’espère que ce tutoriel vous aidera.A bientôt pour un nouveau tutoriel.

Autres ressources

https://kotlinlang.org/docs/reference/delegation.html


Laisser un commentaire

Résoudre : *
26 + 20 =


%d