{"id":917,"date":"2016-02-23T17:15:04","date_gmt":"2016-02-23T15:15:04","guid":{"rendered":"http:\/\/invidit.de\/blog\/?p=917"},"modified":"2020-09-21T11:22:21","modified_gmt":"2020-09-21T09:22:21","slug":"maschinelle-erzeugnisse","status":"publish","type":"post","link":"https:\/\/invidit.de\/blog\/maschinelle-erzeugnisse\/","title":{"rendered":"Maschinelle Erzeugnisse"},"content":{"rendered":"<p>Hallo Spa\u00df-Coder.<\/p>\n<p>In unserem Artikel <a href=\"http:\/\/invidit.de\/blog\/warum-so-gemustert\/\" target=\"_blank\" rel=\"noopener noreferrer\">Warum so gemustert?<\/a> haben wir erl\u00e4utert, welche Bedeutung Muster in der Softwareentwicklung haben. Weiterhin haben wir angek\u00fcndigt, weitere Entwurfsmuster vorzustellen, womit wir uns auch in diesem Artikel auseinander setzten werden.<\/p>\n<p>Wer von euch hat schon einmal ein gro\u00dfes Ganzes bestehend aus mehreren Einzelteilen per Software entwickelt, wie zum Beispiel ein Brettspiel, ein Auto, eine Spielwelt oder ein Haus? All diese Dinge haben gemeinsam, dass sie aus bestimmten Komponenten bestehen. So hat ein Auto \u00fcblicherweise eine Anzahl R\u00e4der, eine Karosserie, ein Motor &#8211; reicht schon fast, oder? \ud83d\ude09 Dabei spielt es keine Rolle, um welches Auto es sich tats\u00e4chlich handelt.<\/p>\n<p>Die naheliegende schnelle Implementierung erfolgt vermutlich sehr konkret. Wenn wir ein Schachspiel entwickeln wollen, w\u00fcrden wir ein passendes Spielbrett erstellen sowie die zugeh\u00f6rigen Spielfiguren. Was nun, wenn wir ein weiteres Brettspiel entwickeln wollen? Nat\u00fcrlich k\u00f6nnen wir dies einfach wieder konkret implementieren. Wer hier genauer hinschaut, entdeckt jedoch schon ein Muster. Ein Brettspiel besteht immer aus einem Spielbrett und Spielfiguren. Diese sind nat\u00fcrlich unterschiedlich in ihren Auspr\u00e4gungen, aber lassen sich entsprechend kategorisieren.<\/p>\n<h1>Der konkrete Hausbau<\/h1>\n<p>Wechseln wir das Beispiel und bauen uns ein Haus \ud83d\ude42 Na gut, ein Fertighaus. Zur Vereinfachung unseres Vorhabens gen\u00fcgt uns ein Haus bestehend aus vier W\u00e4nden, einem Dach und einer T\u00fcre. Je nach Art des Hauses bestehen diese Komponenten aus <a href=\"https:\/\/invidit.de\/blog\/wp-content\/uploads\/2016\/02\/FactoryMethod_tree_house.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignright wp-image-1253\" src=\"https:\/\/invidit.de\/blog\/wp-content\/uploads\/2016\/02\/FactoryMethod_tree_house.png\" alt=\"\" width=\"180\" height=\"164\" srcset=\"https:\/\/invidit.de\/blog\/wp-content\/uploads\/2016\/02\/FactoryMethod_tree_house.png 452w, https:\/\/invidit.de\/blog\/wp-content\/uploads\/2016\/02\/FactoryMethod_tree_house-300x273.png 300w\" sizes=\"(max-width: 180px) 100vw, 180px\" \/><\/a>unterschiedlichen Materialien.<\/p>\n<p>Ein Baumhaus wird vermutlich selten aus Stein, sondern \u00fcberwiegend aus Holz gebaut und anstelle einer einbruchsicheren Stahlt\u00fcre verzichten wir f\u00fcr einen sch\u00f6nen Ausblick einfach auf die Eingangst\u00fcre.<\/p>\n<p>Erstellen wir dazu eine entsprechende Klasse f\u00fcr die Konstruktion der genannten Komponenten, k\u00f6nnte diese wie folgt aussehen:<\/p>\n<pre class=\"lang:java decode:true\">public class TreeHouseFactory {\n    Wall createWall() {\n        return new WoodenWall();\n    }\n\n    Roof createRoof() {\n        return new WoodenRoof();\n    }\n}<\/pre>\n<p><a href=\"https:\/\/invidit.de\/blog\/wp-content\/uploads\/2016\/02\/FactoryMethod_country_house.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignright wp-image-1255\" src=\"https:\/\/invidit.de\/blog\/wp-content\/uploads\/2016\/02\/FactoryMethod_country_house.png\" alt=\"\" width=\"180\" height=\"250\" srcset=\"https:\/\/invidit.de\/blog\/wp-content\/uploads\/2016\/02\/FactoryMethod_country_house.png 318w, https:\/\/invidit.de\/blog\/wp-content\/uploads\/2016\/02\/FactoryMethod_country_house-216x300.png 216w\" sizes=\"(max-width: 180px) 100vw, 180px\" \/><\/a><\/p>\n<p>Hier haben wir eine kleine Fabrik f\u00fcr den Baumhausbau. Wir verwenden die beiden Komponenten <em>Wall<\/em> und <em>Roof<\/em>, welche hier aus Holz erstellt werden. Soweit so gut.<\/p>\n<p>Wie es so ist kommt nun die n\u00e4chste Anforderung und wir sollen neben unserem Baumhaus auch ein Country-Haus erzeugen. Dieses soll aus Holzw\u00e4nden, einem Holzdach sowie einer Holzt\u00fcre bestehen. Nichts leichter als das.<\/p>\n<pre class=\"lang:java decode:true \">public class CountryHouseFactory {\n    Door createDoor() {\n        return new WoodenDoor();\n    }\n\n    Wall createWall() {\n        return new WoodenWall();\n    }\n\n    Roof createRoof() {\n        return new WoodenRoof();\n    }\n}<\/pre>\n<p>Wer von euch besitzt nun scharfe Augen und erkennt im Vergleich mit dem Baumhaus ein Muster? Angenommen wir h\u00e4tten das Baumhaus auch mit einer T\u00fcre ausgestattet, h\u00e4tten wir die gleichen Komponenten(-arten) verwendet.<\/p>\n<p>Dies habt ihr wahrscheinlich schon aus der Aussage abgelesen, dass ein Haus grunds\u00e4tzlich aus bestimmten Komponenten besteht. Welche M\u00f6glichkeiten haben wir nun, dieses Muster nutzbar zu machen?<\/p>\n<h1>Der abstrakte Hausbau<\/h1>\n<p><a href=\"https:\/\/invidit.de\/blog\/wp-content\/uploads\/2016\/02\/abstract_house.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignright wp-image-1252\" src=\"https:\/\/invidit.de\/blog\/wp-content\/uploads\/2016\/02\/abstract_house.png\" alt=\"\" width=\"180\" height=\"205\" srcset=\"https:\/\/invidit.de\/blog\/wp-content\/uploads\/2016\/02\/abstract_house.png 395w, https:\/\/invidit.de\/blog\/wp-content\/uploads\/2016\/02\/abstract_house-264x300.png 264w\" sizes=\"(max-width: 180px) 100vw, 180px\" \/><\/a>Schauen wir uns das Entwurfsmuster <strong>Abstrakte Fabrik<\/strong> (Abstract Factory) im Zusammenhang mit unserem Bauvorhaben f\u00fcr die H\u00e4user an und wie es uns dabei helfen kann, den Code wiederverwendbar und sauber zu strukturieren.<\/p>\n<p>Also noch einmal ganz langsam. Wir ben\u00f6tigen f\u00fcr ein Haus immer W\u00e4nde, ein Dach und eine T\u00fcre &#8211; mit der Option, die T\u00fcre auch weg zu lassen. Dann machen wir daraus doch eine abstrakte Fabrik f\u00fcr H\u00e4user.<\/p>\n<pre class=\"lang:java decode:true\">public abstract class HouseFactory {\n    abstract Door createDoor();\n    abstract Wall createWall();\n    abstract Roof createRoof();\n}<\/pre>\n<p>Genau dies ist das Muster! Egal welches Haus wir bauen wollen, diese Komponenten sind immer mit dabei. Die beiden Fabriken f\u00fcr unser Baumhaus und das Country-Haus lassen sich dahingendend ganz leicht anpassen.<\/p>\n<pre class=\"lang:java decode:true\">public class TreeHouseFactory extends HouseFactory {\n    @Override\n    Door createDoor() {\n        return new NoDoor();\n    }\n\n    @Override\n    Wall createWall() {\n        return new WoodenWall();\n    }\n\n    @Override\n    Roof createRoof() {\n        return new WoodenRoof();\n    }\n}<\/pre>\n<pre class=\"lang:java decode:true\">public class CountryHouseFactory extends HouseFactory {\n    @Override\n    Door createDoor() {\n        return new WoodenDoor();\n    }\n\n    @Override\n    Wall createWall() {\n        return new WoodenWall();\n    }\n\n    @Override\n    Roof createRoof() {\n        return new WoodenRoof();\n    }\n}<\/pre>\n<p>Jede konkrete Fabrik legt damit fest, welche Komponentenarten jeweils dazu geh\u00f6ren. Die Zusammenstellung ist jedoch jedesmal identisch: W\u00e4nde, Dach und T\u00fcre.<\/p>\n<h1>Wann ist dieses Entwurfsmuster sinnvoll anzuwenden?<\/h1>\n<p>Bei diesem Muster geht es darum, Produktfamilien zu erzeugen. Damit sind zusammengeh\u00f6rige Komponenten gemeint, welche in einer bestimmten Konstellation wiederholt auftreten. Zum Beispiel bei GUI-Bibliotheken k\u00f6nnen verschiedene Look &amp; Feels \u00fcber dieses Muster abgebildet werden.<\/p>\n<p>Dabei herauszufinden, wann das Muster sinnvoll eingesetzt werden kann, spielt insbesondere das <a href=\"http:\/\/invidit.de\/blog\/offen-und-geschlossen\/\">Open-Closed-Prinzip<\/a> eine wichtige Rolle. Wie wir in dem Prinzip gelernt haben, wollen wir unseren Code offen f\u00fcr Erweiterungen halten und gleichzeitig geschlossen gegen\u00fcber \u00c4nderungen. Immer dann, wenn wir das Schl\u00fcsselwort <span style=\"color: #993366;\">new<\/span> verwenden, erzeugen wir eine konkrete Abh\u00e4ngigkeit. Immer dann, wenn wir eine konkrete Abh\u00e4ngigkeit haben, verletzen wir das Open-Closed-Prinzip, da wir an dieser Stelle keine Erweiterungen vornehmen k\u00f6nnen, ohne den bestehenden Code zu ver\u00e4ndern.<\/p>\n<p>Wie aber erkennen wir das? Hierzu ist es notwendig, dass wir uns gedanklich von unserem Code trennen und uns auf die konzeptionelle Ebene unserer implementierten L\u00f6sung begeben. Hier m\u00fcssen wir nun Codeteile identifizieren, die sich \u00e4ndern k\u00f6nnen und von denen trennen, die gleich bleiben. F\u00fcr unser H\u00e4userbeispiel bedeutet das:<\/p>\n<ul>\n<li>Bestandteile der einzelnen H\u00e4usertypen <em>\u00e4ndern sich<\/em><\/li>\n<li>Der Vorgang des Hausbaus <em>bleibt gleich<\/em><\/li>\n<\/ul>\n<p>Gleiche Codeteile bleiben unver\u00e4ndert. In unserem Fall sind das die Komponenten selbst und der Client, der diese verwendet, da dieser gegen eine Schnittstelle programmiert ist. Neue\u00a0 H\u00e4usertypen mit ver\u00e4nderten Komponenten lassen sich aber problemlos \u00fcber neue, konkrete Fabriken erg\u00e4nzen.<\/p>\n<h1>Just-in-time Erzeugung<\/h1>\n<p>Wie aber legen wir fest, welche Fabrik wir nun benutzen? Da haben wir doch wieder eine konkrete Abh\u00e4ngigkeit, oder?<\/p>\n<p>Ja, das haben wir tats\u00e4chlich, sobald wir die Fabrik mit <span style=\"color: #993366;\">new<\/span> instanziieren. Diese Abh\u00e4ngigkeit l\u00e4sst sich auch nicht aufl\u00f6sen, irgendwann muss ja festgelegt werden, welche Fabrik nun den Bauauftrag erhalten soll. Wir k\u00f6nnen die Abh\u00e4ngigkeit aber \u00fcber eine Programmiertechnik abschw\u00e4chen, n\u00e4mlich Dependency Injection. Dar\u00fcber legen wir erst zur Laufzeit fest, welche Fabrik tats\u00e4chlich verwendet wird.<\/p>\n<h1>Zusammenfassung<\/h1>\n<p>Wir nutzen die M\u00f6glichkeit der abstrakten Fabrik f\u00fcr die Erzeugung unserer Instanzen, um die ben\u00f6tigten Klassen nicht direkt zu instanziieren, sondern die Erzeugung von der Verwendung zu trennen. Dadurch k\u00f6nnen wir Teile unseres Codes, der sich voraussichtlich \u00e4ndern wird von den Teilen trennen, die sich nicht \u00e4ndern werden. Dies ist eines der Prinzipien guter Software-Entwicklung.<\/p>\n<p>Wir hoffen euch ein weiteres Werkzeug zu eurem K\u00f6fferchen hinzugef\u00fcgt zu haben, dass euch dabei hilft, ein besserer Programmierer zu werden.<\/p>\n<p>Eure Spa\u00df-Coder<\/p>\n<p>Den Code zu unserem Beispiel k\u00f6nnt ihr auf Github finden:<\/p>\n<ul>\n<li>https:\/\/github.com\/invidit\/CodeQuality\/tree\/master\/DesignPattern\/AbstractFactory<\/li>\n<\/ul>\n<p>Dieser Artikel basiert neben unseren Erfahrungen auf den Ausf\u00fchrungen aus:<\/p>\n<ul>\n<li><a href=\"https:\/\/de.wikipedia.org\/wiki\/Abstrakte_Fabrik\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/de.wikipedia.org\/wiki\/Abstrakte_Fabrik<\/a><\/li>\n<li><a href=\"https:\/\/sourcemaking.com\/design_patterns\/abstract_factory\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/sourcemaking.com\/design_patterns\/abstract_factory<\/a><\/li>\n<li><a href=\"http:\/\/www.philipphauer.de\/study\/se\/design-pattern\/abstract-factory.php\" target=\"_blank\" rel=\"noopener noreferrer\">http:\/\/www.philipphauer.de\/study\/se\/design-pattern\/abstract-factory.php<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Hallo Spa\u00df-Coder. In unserem Artikel Warum so gemustert? haben wir erl\u00e4utert, welche Bedeutung Muster in der Softwareentwicklung haben. Weiterhin haben wir angek\u00fcndigt, weitere Entwurfsmuster vorzustellen, womit wir uns auch in diesem Artikel auseinander setzten werden. Wer von euch hat schon einmal ein gro\u00dfes Ganzes bestehend aus mehreren Einzelteilen per Software entwickelt, wie zum Beispiel ein [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":945,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[90],"tags":[131,132,130,129],"_links":{"self":[{"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/posts\/917"}],"collection":[{"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/comments?post=917"}],"version-history":[{"count":29,"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/posts\/917\/revisions"}],"predecessor-version":[{"id":1263,"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/posts\/917\/revisions\/1263"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/media\/945"}],"wp:attachment":[{"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/media?parent=917"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/categories?post=917"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/tags?post=917"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}