{"id":2163,"date":"2019-08-30T22:31:23","date_gmt":"2019-08-30T19:31:23","guid":{"rendered":"http:\/\/demensdeum.com\/blog\/?p=2163"},"modified":"2024-12-16T22:32:35","modified_gmt":"2024-12-16T19:32:35","slug":"pattern-delegate","status":"publish","type":"post","link":"https:\/\/demensdeum.com\/blog\/fr\/2019\/08\/30\/pattern-delegate\/","title":{"rendered":"Mod\u00e8le de d\u00e9l\u00e9gu\u00e9"},"content":{"rendered":"<p>Le mod\u00e8le de d\u00e9l\u00e9gu\u00e9 est l&#8217;un des principaux mod\u00e8les de conception.<br \/>Disons que nous d\u00e9veloppons une application pour salon de coiffure. L&#8217;application dispose d&#8217;un calendrier pour s\u00e9lectionner un jour d&#8217;enregistrement\u00a0; en appuyant sur la date, une liste de barbiers avec un choix devrait s&#8217;ouvrir.<br \/>Impl\u00e9mentons une liaison na\u00efve des composants du syst\u00e8me, combinons le calendrier et l&#8217;\u00e9cran \u00e0 l&#8217;aide de pointeurs les uns vers les autres pour impl\u00e9menter un affichage de liste\u00a0:<\/p>\n<div class=\"hcb_wrap\">\n<pre class=\"prism line-numbers lang-unknown\" data-lang=\"unknown\"><code>\n\/\/ \u043f\u0441\u0435\u0432\u0434\u043e\u043a\u043e\u0434\n\nclass BarbershopScreen {\n   let calendar: Calendar\n\n   func showBarbersList(date: Date) {\n      showSelectionSheet(barbers(forDate: date))\n   }\n}\n\nclass Calendar {\n    let screen: BarbershopScreen\n\n    func handleTap(on date: Date) {\n        screen.showBarbersList(date: date)\n    }\n}\n<\/code><\/pre>\n<\/div>\n<p>Au bout de quelques jours, les exigences changent ; avant d&#8217;afficher la liste, vous devez pr\u00e9senter des offres avec un choix de prestations (taille de barbe, etc.), mais pas toujours, tous les jours sauf le samedi.<br \/>On ajoute au calendrier une v\u00e9rification si c&#8217;est samedi ou non, selon cela, on appelle la m\u00e9thode de la liste des barbiers ou de la liste des services, pour plus de clart\u00e9 je vais d\u00e9montrer\u00a0:<\/p>\n<div class=\"hcb_wrap\">\n<pre class=\"prism line-numbers lang-unknown\" data-lang=\"unknown\"><code>\n\/\/ \u043f\u0441\u0435\u0432\u0434\u043e\u043a\u043e\u0434\n\nclass BarbershopScreen {\n   let calendar: Calendar\n\n   func showBarbersList(date: Date) {\n      showSelectionSheet(barbers(forDate: date))\n   }\n\n   func showOffersList() {\n      showSelectionSheet(offers)\n   }\n}\n\nclass Calendar {\n    let screen: BarbershopScreen\n\n    func handleTap(on date: Date)  {\n        if date.day != .saturday {\n             screen.showOffersList()\n        }\n        else {\n             screen.showBarbersList(date: date)\n        }\n    }\n}\n<\/code><\/pre>\n<\/div>\n<p>Une semaine plus tard, on nous demande d&#8217;ajouter un calendrier \u00e0 l&#8217;\u00e9cran de commentaires, et \u00e0 ce moment-l\u00e0, les premiers oups architecturaux se produisent\u00a0!<br \/>Ce qu&#8217;il faut faire? Le calendrier est \u00e9troitement li\u00e9 \u00e0 l&#8217;\u00e9cran de rendez-vous chez la coupe de cheveux.<br \/>Ouah! Pouah! oh-oh<br \/>Si vous continuez \u00e0 travailler avec cette architecture d&#8217;application folle, vous devez faire une copie de l&#8217;int\u00e9gralit\u00e9 de la classe de calendrier et associer cette copie \u00e0 l&#8217;\u00e9cran de commentaires.<br \/>Ok, \u00e7a a l&#8217;air bien, puis nous avons ajout\u00e9 quelques \u00e9crans suppl\u00e9mentaires et plusieurs copies du calendrier, et puis le moment X est arriv\u00e9. On nous a demand\u00e9 de modifier la conception du calendrier, ce qui signifie que nous devons maintenant trouver toutes les copies du calendrier et ajouter les m\u00eames modifications \u00e0 toutes. Cette \u00ab approche \u00bb affecte grandement la vitesse de d\u00e9veloppement et augmente le risque de commettre une erreur. En cons\u00e9quence, de tels projets se retrouvent dans un \u00e9tat d&#8217;\u00e9chec, lorsque m\u00eame l&#8217;auteur de l&#8217;architecture originale ne comprend plus comment fonctionnent les copies de ses classes, et que d&#8217;autres hacks ajout\u00e9s en cours de route s&#8217;effondrent \u00e0 la vol\u00e9e.<br \/>Que fallait-il faire, ou mieux encore, que n\u2019\u00e9tait-il pas trop tard pour commencer \u00e0 faire ? Utilisez le mod\u00e8le de d\u00e9l\u00e9gation\u00a0!<br \/>La d\u00e9l\u00e9gation est un moyen de transmettre les \u00e9v\u00e9nements de classe via une interface commune. Vous trouverez ci-dessous un exemple de d\u00e9l\u00e9gu\u00e9 pour un calendrier\u00a0:<\/p>\n<div class=\"hcb_wrap\">\n<pre class=\"prism line-numbers lang-unknown\" data-lang=\"unknown\"><code>protocol CalendarDelegate {\n   func calendar(_ calendar: Calendar, didSelect date: Date)\n}\n<\/code><\/pre>\n<\/div>\n<p>Ajoutons maintenant le code permettant de travailler avec le d\u00e9l\u00e9gu\u00e9 \u00e0 l&#8217;exemple de code\u00a0:<\/p>\n<div class=\"hcb_wrap\">\n<pre class=\"prism line-numbers lang-unknown\" data-lang=\"unknown\"><code>\n\/\/ \u043f\u0441\u0435\u0432\u0434\u043e\u043a\u043e\u0434\n\nclass BarbershopScreen: CalendarDelegate {\n   let calendar: Calendar\n\n   init() {\n       calendar.delegate = self\n   }\n\n   func calendar(_ calendar: Calendar, didSelect date: Date) {\n        if date.day != .saturday {\n            showOffersList()\n        }\n        else {\n             showBarbersList(date: date)\n        }\n   }\n\n   func showBarbersList(date: Date) {\n      showSelectionSheet(barbers(forDate: date))\n   }\n\n   func showOffersList() {\n      showSelectionSheet(offers)\n   }\n}\n\nclass Calendar {\n    weak var delegate: CalendarDelegate\n\n    func handleTap(on date: Date)  {\n        delegate?.calendar(self, didSelect: date)\n    }\n}\n<\/code><\/pre>\n<\/div>\n<p>En cons\u00e9quence, nous avons compl\u00e8tement dissoci\u00e9 le calendrier de l&#8217;\u00e9cran\u00a0; lors de la s\u00e9lection d&#8217;une date dans le calendrier, il transmet l&#8217;\u00e9v\u00e9nement de s\u00e9lection de date &#8211; *d\u00e9l\u00e8gue* le traitement des \u00e9v\u00e9nements \u00e0 l&#8217;abonn\u00e9\u00a0; L&#8217;abonn\u00e9 est l&#8217;\u00e9cran.<br \/>Quels avantages tirons-nous de cette approche ? Nous pouvons d\u00e9sormais modifier la logique du calendrier et de l&#8217;\u00e9cran ind\u00e9pendamment les uns des autres sans dupliquer les classes, ce qui simplifie davantage la prise en charge\u00a0; De cette mani\u00e8re, le \u00ab principe de responsabilit\u00e9 exclusive \u00bb pour la mise en \u0153uvre des composants du syst\u00e8me est mis en \u0153uvre et le principe DRY est respect\u00e9.<br \/>Lors de l&#8217;utilisation de la d\u00e9l\u00e9gation, vous pouvez ajouter, modifier la logique d&#8217;affichage des fen\u00eatres, l&#8217;ordre de tout ce qui appara\u00eet \u00e0 l&#8217;\u00e9cran, et cela n&#8217;affectera en rien le calendrier et les autres classes, qui ne devraient objectivement pas participer \u00e0 des processus qui ne leur sont pas directement li\u00e9s.< br \/>Alternativement, les programmeurs qui ne se d\u00e9rangent pas trop utilisent l&#8217;envoi de messages via un bus commun, sans \u00e9crire d&#8217;interface protocole\/d\u00e9l\u00e9gu\u00e9 s\u00e9par\u00e9e, o\u00f9 il serait pr\u00e9f\u00e9rable d&#8217;utiliser la d\u00e9l\u00e9gation. J&#8217;ai parl\u00e9 des inconv\u00e9nients de cette approche dans un article pr\u00e9c\u00e9dent\u00a0: &#8220;Mod\u00e8le d&#8217;observateur.&#8221;<\/p>\n<h3>Sources<\/h3>\n<p><a href=\"https:\/\/refactoring.guru\/ru\/replace-inheritance-with-delegation\" target=\"_blank\" rel=\"noopener\">https:\/\/refactoring.guru\/ru\/replace-inheritance -avec-d\u00e9l\u00e9gation<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Le mod\u00e8le de d\u00e9l\u00e9gu\u00e9 est l&#8217;un des principaux mod\u00e8les de conception.Disons que nous d\u00e9veloppons une application pour salon de coiffure. L&#8217;application dispose d&#8217;un calendrier pour s\u00e9lectionner un jour d&#8217;enregistrement\u00a0; en appuyant sur la date, une liste de barbiers avec un choix devrait s&#8217;ouvrir.Impl\u00e9mentons une liaison na\u00efve des composants du syst\u00e8me, combinons le calendrier et l&#8217;\u00e9cran<a class=\"more-link\" href=\"https:\/\/demensdeum.com\/blog\/fr\/2019\/08\/30\/pattern-delegate\/\">Continue reading <span class=\"screen-reader-text\">&#8220;Mod\u00e8le de d\u00e9l\u00e9gu\u00e9&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[61,52],"tags":[114,95],"class_list":["post-2163","post","type-post","status-publish","format-standard","hentry","category-techie","category-tutorials","tag-delegate","tag-patterns","entry"],"translation":{"provider":"WPGlobus","version":"3.0.2","language":"fr","enabled_languages":["en","ru","zh","de","fr","ja","pt","hi"],"languages":{"en":{"title":true,"content":true,"excerpt":false},"ru":{"title":true,"content":true,"excerpt":false},"zh":{"title":true,"content":true,"excerpt":false},"de":{"title":true,"content":true,"excerpt":false},"fr":{"title":true,"content":true,"excerpt":false},"ja":{"title":true,"content":true,"excerpt":false},"pt":{"title":true,"content":true,"excerpt":false},"hi":{"title":false,"content":false,"excerpt":false}}},"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/demensdeum.com\/blog\/fr\/wp-json\/wp\/v2\/posts\/2163","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/demensdeum.com\/blog\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/demensdeum.com\/blog\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/demensdeum.com\/blog\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/demensdeum.com\/blog\/fr\/wp-json\/wp\/v2\/comments?post=2163"}],"version-history":[{"count":6,"href":"https:\/\/demensdeum.com\/blog\/fr\/wp-json\/wp\/v2\/posts\/2163\/revisions"}],"predecessor-version":[{"id":3946,"href":"https:\/\/demensdeum.com\/blog\/fr\/wp-json\/wp\/v2\/posts\/2163\/revisions\/3946"}],"wp:attachment":[{"href":"https:\/\/demensdeum.com\/blog\/fr\/wp-json\/wp\/v2\/media?parent=2163"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/demensdeum.com\/blog\/fr\/wp-json\/wp\/v2\/categories?post=2163"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/demensdeum.com\/blog\/fr\/wp-json\/wp\/v2\/tags?post=2163"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}