Modèle de délégué

Le modèle de délégué est l’un des principaux modèles de conception.
Disons que nous développons une application pour salon de coiffure. L’application dispose d’un calendrier pour sélectionner un jour d’enregistrement ; en appuyant sur la date, une liste de barbiers avec un choix devrait s’ouvrir.
Implémentons une liaison naïve des composants du système, combinons le calendrier et l’écran à l’aide de pointeurs les uns vers les autres pour implémenter un affichage de liste :


// псевдокод

class BarbershopScreen {
   let calendar: Calendar

   func showBarbersList(date: Date) {
      showSelectionSheet(barbers(forDate: date))
   }
}

class Calendar {
    let screen: BarbershopScreen

    func handleTap(on date: Date) {
        screen.showBarbersList(date: date)
    }
}

Au bout de quelques jours, les exigences changent ; avant d’afficher la liste, vous devez présenter des offres avec un choix de prestations (taille de barbe, etc.), mais pas toujours, tous les jours sauf le samedi.
On ajoute au calendrier une vérification si c’est samedi ou non, selon cela, on appelle la méthode de la liste des barbiers ou de la liste des services, pour plus de clarté je vais démontrer :


// псевдокод

class BarbershopScreen {
   let calendar: Calendar

   func showBarbersList(date: Date) {
      showSelectionSheet(barbers(forDate: date))
   }

   func showOffersList() {
      showSelectionSheet(offers)
   }
}

class Calendar {
    let screen: BarbershopScreen

    func handleTap(on date: Date)  {
        if date.day != .saturday {
             screen.showOffersList()
        }
        else {
             screen.showBarbersList(date: date)
        }
    }
}

Une semaine plus tard, on nous demande d’ajouter un calendrier à l’écran de commentaires, et à ce moment-là, les premiers oups architecturaux se produisent !
Ce qu’il faut faire? Le calendrier est étroitement lié à l’écran de rendez-vous chez la coupe de cheveux.
Ouah! Pouah! oh-oh
Si vous continuez à travailler avec cette architecture d’application folle, vous devez faire une copie de l’intégralité de la classe de calendrier et associer cette copie à l’écran de commentaires.
Ok, ça a l’air bien, puis nous avons ajouté quelques écrans supplémentaires et plusieurs copies du calendrier, et puis le moment X est arrivé. On nous a demandé de modifier la conception du calendrier, ce qui signifie que nous devons maintenant trouver toutes les copies du calendrier et ajouter les mêmes modifications à toutes. Cette « approche » affecte grandement la vitesse de développement et augmente le risque de commettre une erreur. En conséquence, de tels projets se retrouvent dans un état d’échec, lorsque même l’auteur de l’architecture originale ne comprend plus comment fonctionnent les copies de ses classes, et que d’autres hacks ajoutés en cours de route s’effondrent à la volée.
Que fallait-il faire, ou mieux encore, que n’était-il pas trop tard pour commencer à faire ? Utilisez le modèle de délégation !
La délégation est un moyen de transmettre les événements de classe via une interface commune. Vous trouverez ci-dessous un exemple de délégué pour un calendrier :

protocol CalendarDelegate {
   func calendar(_ calendar: Calendar, didSelect date: Date)
}

Ajoutons maintenant le code permettant de travailler avec le délégué à l’exemple de code :


// псевдокод

class BarbershopScreen: CalendarDelegate {
   let calendar: Calendar

   init() {
       calendar.delegate = self
   }

   func calendar(_ calendar: Calendar, didSelect date: Date) {
        if date.day != .saturday {
            showOffersList()
        }
        else {
             showBarbersList(date: date)
        }
   }

   func showBarbersList(date: Date) {
      showSelectionSheet(barbers(forDate: date))
   }

   func showOffersList() {
      showSelectionSheet(offers)
   }
}

class Calendar {
    weak var delegate: CalendarDelegate

    func handleTap(on date: Date)  {
        delegate?.calendar(self, didSelect: date)
    }
}

En conséquence, nous avons complètement dissocié le calendrier de l’écran ; lors de la sélection d’une date dans le calendrier, il transmet l’événement de sélection de date – *délègue* le traitement des événements à l’abonné ; L’abonné est l’écran.
Quels avantages tirons-nous de cette approche ? Nous pouvons désormais modifier la logique du calendrier et de l’écran indépendamment les uns des autres sans dupliquer les classes, ce qui simplifie davantage la prise en charge ; De cette manière, le « principe de responsabilité exclusive » pour la mise en œuvre des composants du système est mis en œuvre et le principe DRY est respecté.
Lors de l’utilisation de la délégation, vous pouvez ajouter, modifier la logique d’affichage des fenêtres, l’ordre de tout ce qui apparaît à l’écran, et cela n’affectera en rien le calendrier et les autres classes, qui ne devraient objectivement pas participer à des processus qui ne leur sont pas directement liés.< br />Alternativement, les programmeurs qui ne se dérangent pas trop utilisent l’envoi de messages via un bus commun, sans écrire d’interface protocole/délégué séparée, où il serait préférable d’utiliser la délégation. J’ai parlé des inconvénients de cette approche dans un article précédent : “Modèle d’observateur.”

Sources

https://refactoring.guru/ru/replace-inheritance -avec-délégation

Leave a Comment

Your email address will not be published. Required fields are marked *