{"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\/de\/2019\/08\/30\/pattern-delegate\/","title":{"rendered":"Delegiertenmuster"},"content":{"rendered":"<p>Das Delegatenmuster ist eines der wichtigsten Entwurfsmuster.<br \/>Nehmen wir an, wir entwickeln eine Friseuranwendung. Die Anwendung verf\u00fcgt \u00fcber einen Kalender zum Ausw\u00e4hlen eines Tages f\u00fcr die Aufzeichnung; durch Tippen auf das Datum sollte eine Liste mit Friseuren mit einer Auswahl ge\u00f6ffnet werden.<br \/>Lassen Sie uns eine naive Verkn\u00fcpfung von Systemkomponenten implementieren, Kalender und Bildschirm mithilfe von Zeigern aufeinander kombinieren, um eine Listenanzeige zu implementieren:<\/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>Nach ein paar Tagen \u00e4ndern sich die Anforderungen; vor der Anzeige der Liste m\u00fcssen Sie Angebote mit einer Auswahl an Dienstleistungen (Bartschneiden usw.) anzeigen, jedoch nicht immer, an allen Tagen au\u00dfer Samstag.<br \/>Wir f\u00fcgen dem Kalender eine Pr\u00fcfung hinzu, ob Samstag ist oder nicht. Abh\u00e4ngig davon nennen wir die Methode der Liste der Friseure oder der Liste der Dienstleistungen. Der \u00dcbersichtlichkeit halber werde ich Folgendes demonstrieren:<\/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>Eine Woche sp\u00e4ter werden wir gebeten, einen Kalender zum Feedback-Bildschirm hinzuzuf\u00fcgen, und in diesem Moment passiert das erste architektonische Ups!<br \/>Was zu tun? Der Kalender ist eng mit dem Friseurtermin-Bildschirm verkn\u00fcpft.<br \/>Wow! Pfui! oh-oh<br \/>Wenn Sie weiterhin mit dieser verr\u00fcckten Anwendungsarchitektur arbeiten, sollten Sie eine Kopie der gesamten Kalenderklasse erstellen und diese Kopie mit dem Feedback-Bildschirm verkn\u00fcpfen.<br \/>Ok, sieht gut aus, dann haben wir noch ein paar Bildschirme und mehrere Kopien des Kalenders hinzugef\u00fcgt, und dann war es soweit. Wir wurden gebeten, das Design des Kalenders zu \u00e4ndern, was bedeutet, dass wir jetzt alle Kopien des Kalenders finden und bei allen die gleichen \u00c4nderungen vornehmen m\u00fcssen. Dieser \u201eAnsatz\u201c hat gro\u00dfen Einfluss auf die Entwicklungsgeschwindigkeit und erh\u00f6ht die Wahrscheinlichkeit, einen Fehler zu machen. Dies hat zur Folge, dass solche Projekte im Chaos enden, wenn selbst der Autor der urspr\u00fcnglichen Architektur nicht mehr versteht, wie Kopien seiner Klassen funktionieren, und andere im Laufe der Zeit hinzugef\u00fcgte Hacks pl\u00f6tzlich auseinanderfallen.<br \/>Was musste getan werden, oder noch besser, womit konnte man noch nicht zu sp\u00e4t beginnen? Verwenden Sie das Delegationsmuster!<br \/>Die Delegation ist eine M\u00f6glichkeit, Klassenereignisse \u00fcber eine gemeinsame Schnittstelle weiterzuleiten. Unten finden Sie ein Beispiel f\u00fcr einen Delegaten f\u00fcr einen Kalender:<\/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>Jetzt f\u00fcgen wir dem Beispielcode den Code f\u00fcr die Arbeit mit dem Delegaten hinzu:<\/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>Daher haben wir den Kalender vollst\u00e4ndig vom Bildschirm entkoppelt. Bei der Auswahl eines Datums aus dem Kalender wird das Datumsauswahlereignis &#8211; *delegiert* die Ereignisverarbeitung an den Abonnenten; Der Abonnent ist der Bildschirm.<br \/>Welche Vorteile ergeben sich f\u00fcr uns aus diesem Ansatz? Jetzt k\u00f6nnen wir die Kalender- und Bildschirmlogik unabh\u00e4ngig voneinander \u00e4ndern, ohne Klassen zu duplizieren, was die weitere Unterst\u00fctzung vereinfacht; Dadurch wird das \u201ePrinzip der Alleinverantwortung\u201c f\u00fcr die Umsetzung von Systemkomponenten umgesetzt und das DRY-Prinzip eingehalten.<br \/>Wenn Sie die Delegation verwenden, k\u00f6nnen Sie die Logik f\u00fcr die Anzeige von Fenstern und die Reihenfolge von allem auf dem Bildschirm hinzuf\u00fcgen und \u00e4ndern. Dies hat keinerlei Auswirkungen auf den Kalender und andere Klassen, die objektiv nicht an Prozessen teilnehmen sollten, die nicht direkt mit ihnen zusammenh\u00e4ngen.< br \/>Alternativ k\u00f6nnen Programmierer, die sich nicht allzu sehr darum k\u00fcmmern, Nachrichten \u00fcber einen gemeinsamen Bus senden, ohne eine separate Protokoll-\/Delegiertenschnittstelle zu schreiben, wo es besser w\u00e4re, die Delegation zu verwenden. Ich habe in einem fr\u00fcheren Beitrag \u00fcber die Nachteile dieses Ansatzes geschrieben &#8211; \u201eBeobachtermuster.\u201c<\/p>\n<h3>Quellen<\/h3>\n<p><a href=\"https:\/\/refactoring.guru\/ru\/replace-inheritance-with-delegation\" target=\"_blank\" rel=\"noopener\">https:\/\/refactoring.guru\/ru\/replace-inheritance -with-delegation<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Das Delegatenmuster ist eines der wichtigsten Entwurfsmuster.Nehmen wir an, wir entwickeln eine Friseuranwendung. Die Anwendung verf\u00fcgt \u00fcber einen Kalender zum Ausw\u00e4hlen eines Tages f\u00fcr die Aufzeichnung; durch Tippen auf das Datum sollte eine Liste mit Friseuren mit einer Auswahl ge\u00f6ffnet werden.Lassen Sie uns eine naive Verkn\u00fcpfung von Systemkomponenten implementieren, Kalender und Bildschirm mithilfe von Zeigern<a class=\"more-link\" href=\"https:\/\/demensdeum.com\/blog\/de\/2019\/08\/30\/pattern-delegate\/\">Continue reading <span class=\"screen-reader-text\">&#8220;Delegiertenmuster&#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":"de","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\/de\/wp-json\/wp\/v2\/posts\/2163","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/demensdeum.com\/blog\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/demensdeum.com\/blog\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/demensdeum.com\/blog\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/demensdeum.com\/blog\/de\/wp-json\/wp\/v2\/comments?post=2163"}],"version-history":[{"count":6,"href":"https:\/\/demensdeum.com\/blog\/de\/wp-json\/wp\/v2\/posts\/2163\/revisions"}],"predecessor-version":[{"id":3946,"href":"https:\/\/demensdeum.com\/blog\/de\/wp-json\/wp\/v2\/posts\/2163\/revisions\/3946"}],"wp:attachment":[{"href":"https:\/\/demensdeum.com\/blog\/de\/wp-json\/wp\/v2\/media?parent=2163"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/demensdeum.com\/blog\/de\/wp-json\/wp\/v2\/categories?post=2163"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/demensdeum.com\/blog\/de\/wp-json\/wp\/v2\/tags?post=2163"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}