{"id":2042,"date":"2019-06-01T13:05:16","date_gmt":"2019-06-01T10:05:16","guid":{"rendered":"http:\/\/demensdeum.com\/blog\/?p=2042"},"modified":"2024-12-16T22:32:37","modified_gmt":"2024-12-16T19:32:37","slug":"bridge-pattern","status":"publish","type":"post","link":"https:\/\/demensdeum.com\/blog\/de\/2019\/06\/01\/bridge-pattern\/","title":{"rendered":"Musterbr\u00fccke"},"content":{"rendered":"<p>Das Br\u00fcckenmuster bezieht sich auf strukturelle Entwurfsmuster. Sie k\u00f6nnen die Implementierung der Klassenlogik abstrahieren, indem Sie die Logik in eine separate abstrakte Klasse verschieben. Klingt einfach, oder?<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-2053\" src=\"https:\/\/demensdeum.com\/blog\/wp-content\/uploads\/2019\/06\/bridge.jpg\" alt=\"\" width=\"380\" height=\"323\" \/><\/p>\n<p>Angenommen, wir implementieren einen Spam-Bot, der in der Lage sein sollte, Nachrichten an verschiedene Arten von Messenger zu senden.<br \/>Wir implementieren es mithilfe eines gemeinsamen Protokolls:<\/p>\n<div class=\"hcb_wrap\">\n<pre class=\"prism line-numbers lang-unknown\" data-lang=\"unknown\"><code>protocol User {\n    let token: String\n    let username: String\n}\n\nprotocol Messenger {\n    var authorize(login: String, password: String)\n    var send(message: String, to user: User)\n}\n\nclass iSeekUUser: User {\n    let token: String\n    let username: String\n}\n\nclass iSeekU: Messenger {\n\n    var authorizedUser: User?\n    var requestSender: RequestSender?\n    var requestFactory: RequestFactory?\n\n    func authorize(login: String, password: String) {\n        authorizedUser = requestSender?.perform(requestFactory.loginRequest(login: login, password: password))\n    }\n    \n    func send(message: String, to user: User) {\n        requestSender?.perform(requestFactory.messageRequest(message: message, to: user)\n    }\n}\n\nclass SpamBot {\n    func start(usersList: [User]) {\n        let iSeekUMessenger = iSeekU()\n        iSeekUMessenger.authorize(login: \"SpamBot\", password: \"SpamPassword\")\n        \n        for user in usersList {\n            iSeekUMessennger.send(message: \"Hey checkout demensdeum blog! http:\/\/demensdeum.com\", to: user)\n        }\n    }\n}\n<\/code><\/pre>\n<\/div>\n<p>Stellen wir uns nun die Ver\u00f6ffentlichung eines neuen, schnelleren Protokolls zum Senden von Nachrichten f\u00fcr den iSekU-Messenger vor. Um ein neues Protokoll hinzuzuf\u00fcgen, m\u00fcssen Sie die Implementierung des iSekU-Bots duplizieren und nur einen kleinen Teil davon \u00e4ndern. Es ist nicht klar, warum dies getan werden sollte, wenn sich nur ein kleiner Teil der Klassenlogik ge\u00e4ndert hat. Bei diesem Ansatz wird das DRY-Prinzip verletzt; bei Weiterentwicklung des Produkts macht sich die fehlende Flexibilit\u00e4t durch Fehler und Verz\u00f6gerungen bei der Implementierung neuer Features bemerkbar.<br \/>Verschieben wir die Logik des Protokolls in eine abstrakte Klasse und implementieren so das Bridge-Muster:<\/p>\n<div class=\"hcb_wrap\">\n<pre class=\"prism line-numbers lang-unknown\" data-lang=\"unknown\"><code>protocol User {\n    let token: String\n    let username: String\n}\n\nprotocol Messenger {\n    var authorize(login: String, password: String)\n    var send(message: String, to user: User)\n}\n\nprotocol MessagesSender {\n    func send(message: String, to user: User)\n}\n\nclass iSeekUUser: User {\n    let token: String\n    let username: String\n}\n\nclass iSeekUFastMessengerSender: MessagesSender {\n    func send(message: String, to user: User) {\n        requestSender?.perform(requestFactory.messageRequest(message: message, to: user)\n    }\n}\n\nclass iSeekU: Messenger {\n\n    var authorizedUser: User?\n    var requestSender: RequestSender?\n    var requestFactory: RequestFactory?\n    var messagesSender: MessengerMessagesSender?\n\n    func authorize(login: String, password: String) {\n        authorizedUser = requestSender?.perform(requestFactory.loginRequest(login: login, password: password))\n    }\n    \n    func send(message: String, to user: User) {\n        messagesSender?.send(message: message, to: user)\n    }\n}\n\nclass SpamBot {\n\n    var messagesSender: MessagesSender?\n\n    func start(usersList: [User]) {\n        let iSeekUMessenger = iSeekU()\n        iSeekUMessenger.authorize(login: \"SpamBot\", password: \"SpamPassword\")\n        \n        for user in usersList {\n            messagesSender.send(message: \"Hey checkout demensdeum blog! http:\/\/demensdeum.com\", to: user)\n        }\n    }\n}\n<\/code><\/pre>\n<\/div>\n<p>Einer der Vorteile dieses Ansatzes ist zweifellos die M\u00f6glichkeit, die Funktionalit\u00e4t der Anwendung durch das Schreiben von Plugins\/Bibliotheken zu erweitern, die abstrahierte Logik implementieren, ohne den Code der Hauptanwendung zu \u00e4ndern.<br \/>Was ist der Unterschied zum Strategiemuster? Beide Muster sind sehr \u00e4hnlich, jedoch beschreibt Strategy das Umschalten von *Algorithmen*, w\u00e4hrend Bridge es Ihnen erm\u00f6glicht, gro\u00dfe Teile *jeder komplexen Logik* zu wechseln.<\/p>\n<h3>Quellen<\/h3>\n<p><a href=\"https:\/\/refactoring.guru\/ru\/design-patterns\/bridge\" target=\"_blank\" rel=\"noopener\">https:\/\/refactoring.guru\/ru\/design-patterns\/bridge <\/a><\/p>\n<h3>Quellcode<\/h3>\n<p><a href=\"https:\/\/gitlab.com\/demensdeum\/patterns\/\" target=\"_blank\" rel=\"noopener\">https:\/\/gitlab.com\/demensdeum\/patterns\/<\/a><\/ a>p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Das Br\u00fcckenmuster bezieht sich auf strukturelle Entwurfsmuster. Sie k\u00f6nnen die Implementierung der Klassenlogik abstrahieren, indem Sie die Logik in eine separate abstrakte Klasse verschieben. Klingt einfach, oder? Angenommen, wir implementieren einen Spam-Bot, der in der Lage sein sollte, Nachrichten an verschiedene Arten von Messenger zu senden.Wir implementieren es mithilfe eines gemeinsamen Protokolls: protocol User {<a class=\"more-link\" href=\"https:\/\/demensdeum.com\/blog\/de\/2019\/06\/01\/bridge-pattern\/\">Continue reading <span class=\"screen-reader-text\">&#8220;Musterbr\u00fccke&#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":[106,95],"class_list":["post-2042","post","type-post","status-publish","format-standard","hentry","category-techie","category-tutorials","tag-bridge","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\/2042","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=2042"}],"version-history":[{"count":12,"href":"https:\/\/demensdeum.com\/blog\/de\/wp-json\/wp\/v2\/posts\/2042\/revisions"}],"predecessor-version":[{"id":3955,"href":"https:\/\/demensdeum.com\/blog\/de\/wp-json\/wp\/v2\/posts\/2042\/revisions\/3955"}],"wp:attachment":[{"href":"https:\/\/demensdeum.com\/blog\/de\/wp-json\/wp\/v2\/media?parent=2042"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/demensdeum.com\/blog\/de\/wp-json\/wp\/v2\/categories?post=2042"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/demensdeum.com\/blog\/de\/wp-json\/wp\/v2\/tags?post=2042"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}