{"id":1966,"date":"2019-05-26T15:02:25","date_gmt":"2019-05-26T15:02:25","guid":{"rendered":"http:\/\/demensdeum.com\/blog\/?p=1966"},"modified":"2024-12-16T22:32:37","modified_gmt":"2024-12-16T19:32:37","slug":"mediator-pattern","status":"publish","type":"post","link":"https:\/\/demensdeum.com\/blog\/de\/2019\/05\/26\/mediator-pattern\/","title":{"rendered":"Mustervermittler"},"content":{"rendered":"<p>Das Mediator-Muster bezieht sich auf Verhaltensdesignmuster.<br \/><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-1995\" src=\"https:\/\/demensdeum.com\/blog\/wp-content\/uploads\/2019\/05\/guitarPick.jpg\" alt=\"\" width=\"320\" height=\"213\" \/><br \/>\nEines Tages erhalten Sie den Auftrag, eine Scherzanwendung zu entwickeln &#8211; Der Benutzer dr\u00fcckt eine Taste in der Mitte des Bildschirms und er ert\u00f6nt das lustige Quaken einer Ente.<br \/>Nach dem Hochladen in den App Store wird die Anwendung zum Hit: Alle quakten \u00fcber Ihre Anwendung, Elon Musk quakt auf seinem Instagram beim n\u00e4chsten Start eines Super-Hochgeschwindigkeitstunnels auf dem Mars, Hillary Clinton qu\u00e4lt Donald Trump bei der Debatte und gewinnt die Wahlen in der Ukraine, Erfolg!<br \/>Die naive Implementierung der Anwendung sieht folgenderma\u00dfen aus:<\/p>\n<div class=\"hcb_wrap\">\n<pre class=\"prism line-numbers lang-unknown\" data-lang=\"unknown\"><code>class DuckButton {\n    func didPress() {\n        print(\"quack!\")\n    }\n}\n\nlet duckButton = DuckButton()\nduckButton.didPress()\n<\/code><\/pre>\n<\/div>\n<p>Als n\u00e4chstes entscheiden Sie sich, das Ger\u00e4usch eines Hundegebells hinzuzuf\u00fcgen. Dazu m\u00fcssen Sie zwei Schaltfl\u00e4chen zur Auswahl des Ger\u00e4uschs anzeigen &#8211; mit einer Ente und einem Hund. Lassen Sie uns zwei Schaltfl\u00e4chenklassen erstellen: DuckButton und DogButton.<br \/>\u00c4ndern Sie den Code:<\/p>\n<div class=\"hcb_wrap\">\n<pre class=\"prism line-numbers lang-unknown\" data-lang=\"unknown\"><code>class DuckButton {\n    func didPress() {\n        print(\"quack!\")\n    }\n}\n\nclass DogButton {\n    func didPress() {\n        print(\"bark!\")\n    }\n}\n\nlet duckButton = DuckButton()\nduckButton.didPress()\n\nlet dogButton = DogButton()\ndogButton.didPress()\n<\/code><\/pre>\n<\/div>\n<p>Nach einem weiteren Erfolg f\u00fcgen wir den Klang eines Schweinequietschens hinzu, jetzt gibt es drei Klassen von Tasten:<\/p>\n<div class=\"hcb_wrap\">\n<pre class=\"prism line-numbers lang-unknown\" data-lang=\"unknown\"><code>class DuckButton {\n    func didPress() {\n        print(\"quack!\")\n    }\n}\n\nclass DogButton {\n    func didPress() {\n        print(\"bark!\")\n    }\n}\n\nclass PigButton {\n    func didPress() {\n        print(\"oink!\")\n    }\n}\n\nlet duckButton = DuckButton()\nduckButton.didPress()\n\nlet dogButton = DogButton()\ndogButton.didPress()\n\nlet pigButton = PigButton()\npigButton.didPress()\n<\/code><\/pre>\n<\/div>\n<p>Benutzer beschweren sich dar\u00fcber, dass sich die Ger\u00e4usche \u00fcberlappen.<br \/>Wir f\u00fcgen eine Pr\u00fcfung hinzu, um dies zu verhindern, und stellen gleichzeitig die Klassen einander vor:<\/p>\n<div class=\"hcb_wrap\">\n<pre class=\"prism line-numbers lang-unknown\" data-lang=\"unknown\"><code>class DuckButton {\n    var isMakingSound = false\n    var dogButton: DogButton?\n    var pigButton: PigButton?\n    func didPress() {\n        guard dogButton?.isMakingSound ?? false == false &&\n                pigButton?.isMakingSound ?? false == false else { return }\n        isMakingSound = true\n        print(\"quack!\")\n        isMakingSound = false\n    }\n}\n\nclass DogButton {\n    var isMakingSound = false\n    var duckButton: DuckButton?\n    var pigButton: PigButton?\n    func didPress() {\n        guard duckButton?.isMakingSound ?? false == false &&\n                pigButton?.isMakingSound ?? false == false else { return }\n        isMakingSound = true\n        print(\"bark!\")\n        isMakingSound = false\n    }\n}\n\nclass PigButton {\n    var isMakingSound = false\n    var duckButton: DuckButton?\n    var dogButton: DogButton?\n    func didPress() {\n        guard duckButton?.isMakingSound ?? false == false && \n                dogButton?.isMakingSound ?? false == false else { return }\n        isMakingSound = true\n        print(\"oink!\")\n        isMakingSound = false\n    }\n}\n\nlet duckButton = DuckButton()\nduckButton.didPress()\n\nlet dogButton = DogButton()\ndogButton.didPress()\n\nlet pigButton = PigButton()\npigButton.didPress()\n<\/code><\/pre>\n<\/div>\n<p>Aufgrund des Erfolgs Ihres Antrags beschlie\u00dft die Regierung, ein Gesetz zu erlassen, nach dem das Quacksalbern, Bellen und Grunzen auf Mobilger\u00e4ten an den restlichen Wochentagen nur von 9:00 bis 15:00 Uhr erfolgen darf Zu diesem Zeitpunkt riskiert der Benutzer Ihrer Anwendung eine Gef\u00e4ngnisstrafe von 5 Jahren wegen obsz\u00f6ner Tonproduktion mit pers\u00f6nlichen elektronischen Ger\u00e4ten.<br \/>\u00c4ndern Sie den Code:<\/p>\n<div class=\"hcb_wrap\">\n<pre class=\"prism line-numbers lang-unknown\" data-lang=\"unknown\"><code>import Foundation\n\nextension Date {\n    func mobileDeviceAllowedSoundTime() -> Bool {\n        let hour = Calendar.current.component(.hour, from: self)\n        let weekend = Calendar.current.isDateInWeekend(self)\n        \n        let result = hour >= 9 && hour <= 14 &#038;&#038; weekend == false\n        \n        return result\n    }\n}\n\nclass DuckButton {\n    var isMakingSound = false\n    var dogButton: DogButton?\n    var pigButton: PigButton?\n    func didPress() {\n        guard dogButton?.isMakingSound ?? false == false &#038;&#038;\n                pigButton?.isMakingSound ?? false == false &#038;&#038;\n                 Date().mobileDeviceAllowedSoundTime() == true else { return }\n        isMakingSound = true\n        print(\"quack!\")\n        isMakingSound = false\n    }\n}\n\nclass DogButton {\n    var isMakingSound = false\n    var duckButton: DuckButton?\n    var pigButton: PigButton?\n    func didPress() {\n        guard duckButton?.isMakingSound ?? false == false &#038;&#038;\n                pigButton?.isMakingSound ?? false == false &#038;&#038;\n                 Date().mobileDeviceAllowedSoundTime() == true else { return }\n        isMakingSound = true\n        print(\"bark!\")\n        isMakingSound = false\n    }\n}\n\nclass PigButton {\n    var isMakingSound = false\n    var duckButton: DuckButton?\n    var dogButton: DogButton?\n    func didPress() {\n        guard duckButton?.isMakingSound ?? false == false &#038;&#038; \n                dogButton?.isMakingSound ?? false == false &#038;&#038;\n                 Date().mobileDeviceAllowedSoundTime() == true else { return }\n        isMakingSound = true\n        print(\"oink!\")\n        isMakingSound = false\n    }\n}\n\nlet duckButton = DuckButton()\nlet dogButton = DogButton()\nlet pigButton = PigButton()\n\nduckButton.dogButton = dogButton\nduckButton.pigButton = pigButton\n\ndogButton.duckButton = duckButton\ndogButton.pigButton = pigButton\n\npigButton.duckButton = duckButton\npigButton.dogButton = dogButton\n\nduckButton.didPress()\ndogButton.didPress()\npigButton.didPress()\n<\/code><\/pre>\n<\/div>\n<p>Pl\u00f6tzlich f\u00e4ngt die Taschenlampen-Anwendung an, unsere vom Markt zu verdr\u00e4ngen. Lassen wir uns davon nicht unterkriegen und f\u00fcgen wir eine Taschenlampe hinzu, indem wir die \u201eoink-oink\u201c-Taste und die restlichen Tasten dr\u00fccken:<\/p>\n<div class=\"hcb_wrap\">\n<pre class=\"prism line-numbers lang-unknown\" data-lang=\"unknown\"><code>import Foundation\n\nextension Date {\n    func mobileDeviceAllowedSoundTime() -> Bool {\n        let hour = Calendar.current.component(.hour, from: self)\n        let weekend = Calendar.current.isDateInWeekend(self)\n        \n        let result = hour >= 9 && hour <= 14 &#038;&#038; weekend == false\n        \n        return result\n    }\n}\n\nclass Flashlight {\n\n    var isOn = false\n\n    func turn(on: Bool) {\n        isOn = on\n    }\n}\n\nclass DuckButton {\n    var isMakingSound = false\n    var dogButton: DogButton?\n    var pigButton: PigButton?\n    var flashlight: Flashlight?\n    func didPress() {\n        flashlight?.turn(on: true)\n        guard dogButton?.isMakingSound ?? false == false &#038;&#038;\n                pigButton?.isMakingSound ?? false == false &#038;&#038;\n                 Date().mobileDeviceAllowedSoundTime() == true else { return }\n        isMakingSound = true\n        print(\"quack!\")\n        isMakingSound = false\n    }\n}\n\nclass DogButton {\n    var isMakingSound = false\n    var duckButton: DuckButton?\n    var pigButton: PigButton?\n    var flashlight: Flashlight?\n    func didPress() {\n        flashlight?.turn(on: true)\n        guard duckButton?.isMakingSound ?? false == false &#038;&#038;\n                pigButton?.isMakingSound ?? false == false &#038;&#038;\n                 Date().mobileDeviceAllowedSoundTime() == true else { return }\n        isMakingSound = true\n        print(\"bark!\")\n        isMakingSound = false\n    }\n}\n\nclass PigButton {\n    var isMakingSound = false\n    var duckButton: DuckButton?\n    var dogButton: DogButton?\n    var flashlight: Flashlight?\n    func didPress() {\n        flashlight?.turn(on: true)\n        guard duckButton?.isMakingSound ?? false == false &#038;&#038; \n                dogButton?.isMakingSound ?? false == false &#038;&#038;\n                 Date().mobileDeviceAllowedSoundTime() == true else { return }\n        isMakingSound = true\n        print(\"oink!\")\n        isMakingSound = false\n    }\n}\n\nlet flashlight = Flashlight()\nlet duckButton = DuckButton()\nlet dogButton = DogButton()\nlet pigButton = PigButton()\n\nduckButton.dogButton = dogButton\nduckButton.pigButton = pigButton\nduckButton.flashlight = flashlight\n\ndogButton.duckButton = duckButton\ndogButton.pigButton = pigButton\ndogButton.flashlight = flashlight\n\npigButton.duckButton = duckButton\npigButton.dogButton = dogButton\npigButton.flashlight = flashlight\n\nduckButton.didPress()\ndogButton.didPress()\npigButton.didPress()\n<\/code><\/pre>\n<\/div>\n<p>Als Ergebnis haben wir eine riesige Anwendung, die viel Copy-Paste-Code enth\u00e4lt, die Klassen darin sind durch einen toten Link miteinander verbunden \u2013 es gibt keine schwache Kopplung, ein solches Wunder ist sehr schwer zu warten und \u00c4nderungen in der Zukunft aufgrund der hohen Wahrscheinlichkeit, dass ein Fehler gemacht wird.<\/p >\n<h3>Verwenden Sie den Mediator<\/h3>\n<p>F\u00fcgen wir eine mittlere Mediatorklasse hinzu \u2013 ApplicationController. Diese Klasse sorgt f\u00fcr eine lose Kopplung von Objekten, gew\u00e4hrleistet die Trennung der Verantwortlichkeiten zwischen den Klassen und eliminiert doppelten Code.<br \/>Schreiben wir um:<\/p>\n<div class=\"hcb_wrap\">\n<pre class=\"prism line-numbers lang-unknown\" data-lang=\"unknown\"><code>import Foundation\n\nclass ApplicationController {\n\n    private var isMakingSound = false\n    private let flashlight = Flashlight()\n    private var soundButtons: [SoundButton] = []\n\n    func add(soundButton: SoundButton) {\n        soundButtons.append(soundButton)\n    }\n    \n    func didPress(soundButton: SoundButton) {\n        flashlight.turn(on: true)\n        guard Date().mobileDeviceAllowedSoundTime() && \n                isMakingSound == false else { return }\n        isMakingSound = true\n        soundButton.didPress()\n        isMakingSound = false\n    }\n}\n\nclass SoundButton {\n    let soundText: String\n    \n    init(soundText: String) {\n        self.soundText = soundText\n    }\n    \n    func didPress() {\n        print(soundText)\n    }\n}\n\nclass Flashlight {\n    var isOn = false\n\n    func turn(on: Bool) {\n        isOn = on\n    }\n}\n\nextension Date {\n    func mobileDeviceAllowedSoundTime() -> Bool {\n        let hour = Calendar.current.component(.hour, from: self)\n        let weekend = Calendar.current.isDateInWeekend(self)\n        \n        let result = hour >= 9 && hour <= 14 &#038;&#038; weekend == false\n        \n        return result\n    }\n}\n\nlet applicationController = ApplicationController()\nlet pigButton = SoundButton(soundText: \"oink!\")\nlet dogButton = SoundButton(soundText: \"bark!\")\nlet duckButton = SoundButton(soundText: \"quack!\")\n\napplicationController.add(soundButton: pigButton)\napplicationController.add(soundButton: dogButton)\napplicationController.add(soundButton: duckButton)\n\npigButton.didPress()\ndogButton.didPress()\nduckButton.didPress()\n<\/code><\/pre>\n<\/div>\n<p>Viele Artikel \u00fcber Anwendungsarchitekturen f\u00fcr Benutzeroberfl\u00e4chen beschreiben das MVC-Muster und seine Ableitungen. Das Modell wird f\u00fcr die Arbeit mit Gesch\u00e4ftslogikdaten verwendet. Die Ansicht oder Pr\u00e4sentation zeigt dem Benutzer Informationen in der Schnittstelle an bzw. sorgt f\u00fcr die Interaktion mit dem Benutzer. Der Controller ist ein Vermittler, der die Interaktion der Systemkomponenten sicherstellt.<\/p>\n<h3>Quellen<\/h3>\n<p><a href=\"https:\/\/refactoring.guru\/ru\/design-patterns\/mediator\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/refactoring.guru\/ru\/design-patterns\/ Vermittler<\/a><\/p>\n<h3>Quellcode<\/h3>\n<p><a href=\"https:\/\/gitlab.com\/demensdeum\/patterns\/\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/gitlab.com\/demensdeum\/patterns\/<\/a>< \/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Das Mediator-Muster bezieht sich auf Verhaltensdesignmuster. Eines Tages erhalten Sie den Auftrag, eine Scherzanwendung zu entwickeln &#8211; Der Benutzer dr\u00fcckt eine Taste in der Mitte des Bildschirms und er ert\u00f6nt das lustige Quaken einer Ente.Nach dem Hochladen in den App Store wird die Anwendung zum Hit: Alle quakten \u00fcber Ihre Anwendung, Elon Musk quakt auf<a class=\"more-link\" href=\"https:\/\/demensdeum.com\/blog\/de\/2019\/05\/26\/mediator-pattern\/\">Continue reading <span class=\"screen-reader-text\">&#8220;Mustervermittler&#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":[103,95],"class_list":["post-1966","post","type-post","status-publish","format-standard","hentry","category-techie","category-tutorials","tag-mediator","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\/1966","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=1966"}],"version-history":[{"count":31,"href":"https:\/\/demensdeum.com\/blog\/de\/wp-json\/wp\/v2\/posts\/1966\/revisions"}],"predecessor-version":[{"id":3958,"href":"https:\/\/demensdeum.com\/blog\/de\/wp-json\/wp\/v2\/posts\/1966\/revisions\/3958"}],"wp:attachment":[{"href":"https:\/\/demensdeum.com\/blog\/de\/wp-json\/wp\/v2\/media?parent=1966"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/demensdeum.com\/blog\/de\/wp-json\/wp\/v2\/categories?post=1966"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/demensdeum.com\/blog\/de\/wp-json\/wp\/v2\/tags?post=1966"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}