{"id":1067,"date":"2016-07-05T16:15:25","date_gmt":"2016-07-05T14:15:25","guid":{"rendered":"http:\/\/invidit.de\/blog\/?p=1067"},"modified":"2016-07-05T08:39:54","modified_gmt":"2016-07-05T06:39:54","slug":"im-fruehjahr-waechst-der-baum","status":"publish","type":"post","link":"https:\/\/invidit.de\/blog\/im-fruehjahr-waechst-der-baum\/","title":{"rendered":"Im Fr\u00fchjahr w\u00e4chst&#8230;der Baum"},"content":{"rendered":"<p>Hallo Spa\u00df-Coder.<\/p>\n<p>Weiter geht es mit unserer Reihe \u00fcber <em>Entwurfsmuster, <\/em>heute mit einem weiteren Muster aus der Kategorie der <em>Strukturmuster. <\/em>Wir schauen uns in diesem Artikel den <strong>Kompositum <\/strong>(engl. Composite) an, der auch aus der Sammlung der Gang of Four stammt.<\/p>\n<p>&nbsp;<\/p>\n<h1>Kompo&#8230;was?<\/h1>\n<p>Kompositum (oder auch Teile-Ganzes genannt) ist ein einfaches Muster um Hierarchien von Objekten abzubilden. Ein simples Beispiel dazu ist eine Baumstruktur wie bei einem Men\u00fc, bei dem es einen Einstiegspunkt, darunter Untermen\u00fcs und darunter ggf. wiederum weitere Untermen\u00fcs gibt. Die Besonderheit bei diesem Muster ist, dass alle Bestandteile der Hierarchie &#8211; egal ob auf der untersten Ebene (<strong>Blatt<\/strong> genannt) oder mitten im Baum (im Baum <strong>Knoten<\/strong> genannt) &#8211; gleich behandelt werden k\u00f6nnen. Alle Klassen implementieren dabei dieselbe Schnittstelle.<\/p>\n<p>&nbsp;<\/p>\n<h1>Wie funktioniert das Kompositum?<\/h1>\n<p>Schauen wir uns einmal eine Implementierung mit Hilfe des Kompositum an und nehmen dabei allerdings nicht das bereits oben erw\u00e4hnte klassische Beispiel des Men\u00fcbaums. Machen wir es etwas interessanter &#8230; damit hat jetzt niemand <strong><em>gerechnet<\/em><\/strong>, oder?<\/p>\n<p>Das nachfolgende Beispiel ist bez\u00fcglich des Kompositum vielleicht etwas ungew\u00f6hnlich. Dies soll jedoch aufzeigen, dass auch spezielle Arten von Baumstrukturen abgebildet werden k\u00f6nnen. Alles beginnt mit der einen Schnittstelle, die sp\u00e4ter von den Knoten und Bl\u00e4ttern implementiert wird.<\/p>\n<pre class=\"lang:java decode:true\">public interface Computable {\r\n    double compute();\r\n}<\/pre>\n<p>In unserem Fall soll etwas berechnet und das Ergebnis vom Typ <em>double<\/em> zur\u00fcckgegeben werden. Unser Blatt des Baums ist eine einfache Zahl. Nennen wir die Klasse <em>Operand<\/em>, sieht der Code dazu wie folgt aus.<\/p>\n<pre class=\"lang:java decode:true\">public class Operand implements Computable {\r\n\r\n    private double value;\r\n\r\n    public Operand(double value) {\r\n        this.value = value;\r\n    }\r\n\r\n    @Override\r\n    public double compute() {\r\n        return this.value;\r\n    }\r\n}<\/pre>\n<p>Hier wird der per Konstruktor einmalig gesetzte Wert zur\u00fcckgegeben. Soweit so einfach. Nun der <em>Operator<\/em>.<\/p>\n<pre class=\"lang:java decode:true\">public class Operator implements Computable {\r\n\r\n    private ComputingStrategy computingStrategy;\r\n    private Computable firstOperand;\r\n    private Computable secondOperand;\r\n\r\n    public Operator(Computable firstOperand, ComputingStrategy computingStrategy, Computable secondOperand) {\r\n        this.computingStrategy = computingStrategy;\r\n        this.firstOperand = firstOperand;\r\n        this.secondOperand = secondOperand;\r\n    }\r\n\r\n    @Override\r\n    public double compute() {\r\n        return this.computingStrategy.compute(firstOperand, secondOperand);\r\n    }\r\n}<\/pre>\n<p>Hier schauen wir einmal genauer hin, auch wenn sich die Funktionsweise vermutlich fast von selbst erkl\u00e4rt. Ein Operator besteht aus einem Operanden, aus einer Rechenvorschrift und einem weiteren Operanden. Somit k\u00f6nnten wir z.B. die Rechnung 5 + 4 abbilden. Um eine gr\u00f6\u00dftm\u00f6gliche Flexibilit\u00e4t bei der Rechenvorschrift zu haben nutzen wir hier das <a href=\"http:\/\/invidit.de\/blog\/ein-guter-plan-hmm-oder-der-oder-doch-der-andere\/\">Strategie-Muster<\/a>.<\/p>\n<pre class=\"lang:java decode:true\">public interface ComputingStrategy {\r\n    double compute(Computable firstOperand, Computable secondOperand);\r\n}<\/pre>\n<p>Hier werden zwei Operanden miteinander verkn\u00fcpft. F\u00fcr die Addition haben wir damit folgende Implementierung.<\/p>\n<pre class=\"lang:java decode:true\">public class Plus implements ComputingStrategy {\r\n    @Override\r\n    public double compute(Computable firstOperand, Computable secondOperand) {\r\n        return firstOperand.compute() + secondOperand.compute();\r\n    }\r\n}<\/pre>\n<p>F\u00fcr die Verkn\u00fcpfung der Operanden wird der jeweilige Wert \u00fcber die Methode <em>compute()<\/em> ermittelt. Vielleicht ahnt der ein oder andere von euch an dieser Stelle schon so etwas wie Rekursion und liegt damit ganz richtig. Wir verwenden f\u00fcr die Verkn\u00fcpfung innerhalb der Rechenvorschrift nur das Interface <em>Computable<\/em>. Demnach ist es egal, ob es sich dabei um ein Operand oder ein Operator handelt. Dies genau ist die St\u00e4rke des Kompositum: alle Bestandteile des Baum werden gleich behandelt!<\/p>\n<p>Ein Test der Implementierung der Addition ist an dieser Stelle schon ziemlich gr\u00fcn \ud83d\ude42<\/p>\n<pre class=\"lang:java decode:true \">@Test\r\npublic void testComputeCalcsCorrectWithoutDecimalValues() throws Exception {\r\n    Operand five = new Operand(5d);\r\n    Operand four = new Operand(4d);\r\n    ComputingStrategy sut = new Plus();\r\n    Assertions.assertThat(sut.compute(five, four)).isEqualTo(9d, Offset.offset(0.0));\r\n}<\/pre>\n<p>Eine kleine Rechnung mit verschiedenen Rechenschritten l\u00e4sst sich nun in dieser Form gestalten.<\/p>\n<pre class=\"lang:java decode:true \">public class CompositeExample {\r\n    public static void main(String...args) {\r\n        Operand five = new Operand(5d);\r\n        Operand four = new Operand(4d);\r\n        Operand two = new Operand(2d);\r\n\r\n        Operator fivePlusFour = new Operator(five, new Plus(), four);\r\n        Operator twoTimesNine = new Operator(two, new Multiplication(), fivePlusFour);\r\n        Operator eighteenDividedByFour = new Operator(twoTimesNine, new Division(), four);\r\n\r\n        System.out.print(\"(5 + 4) * 2 \/ 4 = \");\r\n        System.out.println(eighteenDividedByFour.compute());\r\n    }\r\n}<\/pre>\n<p>Wir &#8222;bauen&#8220; die Rechnung nun als Baum auf und rufen einmalig die Methode <em>compute()<\/em> auf und erhalten das Gesamtergebnis. Wichtig dabei zu beachten ist, dass unsere Rechnung immer linksseitig ausgewertet wird! Dies liegt daran, dass in der Rechenvorschrift\u00a0 zuerst <em>firstOperand.compute()<\/em> aufgerufen wird. Grafisch dargestellt sieht unser Baum aus obigem Beispiel so aus:<\/p>\n<p><a href=\"http:\/\/invidit.de\/blog\/wp-content\/uploads\/2016\/04\/Composite_logo.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-1075\" src=\"http:\/\/invidit.de\/blog\/wp-content\/uploads\/2016\/04\/Composite_logo.png\" alt=\"Composite_logo\" width=\"490\" height=\"589\" srcset=\"https:\/\/invidit.de\/blog\/wp-content\/uploads\/2016\/04\/Composite_logo.png 490w, https:\/\/invidit.de\/blog\/wp-content\/uploads\/2016\/04\/Composite_logo-250x300.png 250w\" sizes=\"(max-width: 490px) 100vw, 490px\" \/><\/a><\/p>\n<p>&nbsp;<\/p>\n<h1>Besonderheit des Beispiels<\/h1>\n<p>Zu unserem Beispiel ist noch zu sagen, dass hier gegen\u00fcber der \u00fcblichen Verwendung des Kompositums eine Besonderheit vorliegt. Unser <em>Operand<\/em> enth\u00e4lt exakt zwei Variablen vom Typ <em>Computable<\/em>. H\u00e4ufig ist es jedoch so, dass ein Baumknoten eine Liste von Komponenten enth\u00e4lt, die bei der Verarbeitung iteriert wird. Die Grundidee bleibt jedoch dieselbe &#8211; Knoten und Bl\u00e4tter des Baums werden durch die Implementierung derselben Schnittstelle identisch verwendet. Demnach muss der Nutzer keine Kenntnis dar\u00fcber haben, um welche Art von Komponente es sich handelt.<\/p>\n<p>&nbsp;<\/p>\n<h1>Zusammenfassung?<\/h1>\n<p>Wir haben uns in diesem Artikel ein <em>Strukturmuster<\/em> aus der Liste der Entwurfsmuster angeschaut, mit welchem eine Baumstruktur oder Teile-Ganzes-Beziehung abgebildet werden kann. Dies kann f\u00fcr Men\u00fcs, Unternehmenshierarchien oder Berechnungen genutzt werden. Mit der einmalig festgelegten Schnittstelle kann der Baum auch sehr einfach um weitere Implementierungen von Komponenten erweitert werden, welche dann nach belieben orchestriert werden k\u00f6nnen.<\/p>\n<p>In welcher Situation habt ihr schon einmal einen Baum wachsen lassen?<\/p>\n<p>&nbsp;<\/p>\n<p>Eure Spa\u00df-Coder<\/p>\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\/Kompositum_%28Entwurfsmuster%29\">https:\/\/de.wikipedia.org\/wiki\/Kompositum_%28Entwurfsmuster%29<\/a><\/li>\n<\/ul>\n<p>Code-Beispiele auf Github:<\/p>\n<ul>\n<li>https:\/\/github.com\/invidit\/CodeQuality.git<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Hallo Spa\u00df-Coder. Weiter geht es mit unserer Reihe \u00fcber Entwurfsmuster, heute mit einem weiteren Muster aus der Kategorie der Strukturmuster. Wir schauen uns in diesem Artikel den Kompositum (engl. Composite) an, der auch aus der Sammlung der Gang of Four stammt. &nbsp; Kompo&#8230;was? Kompositum (oder auch Teile-Ganzes genannt) ist ein einfaches Muster um Hierarchien von [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":1075,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[90],"tags":[139,130,141],"_links":{"self":[{"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/posts\/1067"}],"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=1067"}],"version-history":[{"count":15,"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/posts\/1067\/revisions"}],"predecessor-version":[{"id":1163,"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/posts\/1067\/revisions\/1163"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/media\/1075"}],"wp:attachment":[{"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/media?parent=1067"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/categories?post=1067"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/tags?post=1067"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}