{"id":1086,"date":"2016-05-03T16:15:10","date_gmt":"2016-05-03T14:15:10","guid":{"rendered":"http:\/\/invidit.de\/blog\/?p=1086"},"modified":"2016-05-03T18:22:42","modified_gmt":"2016-05-03T16:22:42","slug":"ein-guter-plan-hmm-oder-der-oder-doch-der-andere","status":"publish","type":"post","link":"https:\/\/invidit.de\/blog\/ein-guter-plan-hmm-oder-der-oder-doch-der-andere\/","title":{"rendered":"Ein guter Plan! Hmm, oder der? Oder doch der andere?"},"content":{"rendered":"<p>Hallo Spa\u00df-Coder.<\/p>\n<p>Mit einem weiteren Thema aus unserer Reihe \u00fcber <em>Entwurfsmuster <\/em>geht es nun munter weiter. Wir werden uns nun einmal mit einem Mustern aus der Kategorie der <em>Verhaltensmuster besch\u00e4ftigen. <\/em>Wir schauen uns in diesem Artikel das <strong>Strategie-Muster <\/strong>(engl. Strategy Pattern) an, ebenfalls aus der Sammlung der Gang of Four.<\/p>\n<p>&nbsp;<\/p>\n<h1>Was ist denn das, eine Strategie?<\/h1>\n<p>Der Begriff der Strategie stammt aus der Kriegsf\u00fchrung und bezeichnet laut Duden einen<\/p>\n<blockquote><p>genaue[n] Plan des eigenen Vorgehens, der dazu dient, ein milit\u00e4risches, politisches, psychologisches, wirtschaftliches o. \u00e4. Ziel zu erreichen, [&#8230;]<\/p><\/blockquote>\n<p>Dabei werden unterschiedliche Fakten in die Entscheidung f\u00fcr ein Vorgehen einbezogen. Diese Fakten k\u00f6nnen nat\u00fcrlich zu unterschiedlichen Vorgehen f\u00fchren, weshalb es ratsam ist, f\u00fcr unterschiedliche Situationen unterschiedliche Strategien in petto zu haben.<\/p>\n<p>Was bedeuten diese Erkenntnisse nun f\u00fcr die Softwareentwicklung? Was bedeutet es f\u00fcr unsere Architektur?<\/p>\n<p>Um auf unterschiedliche Situationen (Anforderungen) reagieren zu k\u00f6nnen, k\u00f6nnen wir das Strategie-Muster nutzen. Dazu \u00fcbergeben wir unserer Klasse einfach den Teil der Implementierung, der sich ver\u00e4ndern kann. Hierbei folgen wir dem <a href=\"http:\/\/invidit.de\/blog\/offen-und-geschlossen\/\">Open-Closed-<\/a> und dem\u00a0<a href=\"http:\/\/invidit.de\/blog\/aus-prinzip-nur-eine-verantwortlichkeit\/\">Single-Responsibility-Prinzip<\/a>.<\/p>\n<p>Die \u00fcbergebenen Strategien m\u00fcssen dabei dieselbe Schnittstelle implementieren, damit wir sie nutzen k\u00f6nnen.<\/p>\n<p>&nbsp;<\/p>\n<h1>Wie funktioniert das Strategie-Muster?<\/h1>\n<p>Beim Strategie-Muster wird einer Klasse ein Objekt \u00fcbergeben, welche das Verhalten der Klasse beeinflusst. Durch dieses injizierte Verhalten muss die eigentliche Klasse nicht mehr alle Entscheidungen treffen, sondern kann die Anforderungen, die von au\u00dfen gestellt werden, direkt unterst\u00fctzen. Das Verhalten wird also von au\u00dfen vorgegeben.<\/p>\n<p>&nbsp;<\/p>\n<h2>Das ist doch alles nur ein Spiel<\/h2>\n<p>Nehmen wir als Beispiel noch einmal unser altbekanntes Tic-Tac-Toe.<\/p>\n<p>Die Idee ist es, das Spiel dahingehend flexibel zu gestalten, welche Art von Spieler am Spiel teilnimmt. So kann es ein menschlicher Spieler sein, aber auch eine KI, eine k\u00fcnstliche Intelligenz. Diese wiederum kann unterschiedlich implementiert werden. Vielleicht auf Basis von Zufall? Oder nach dem <a href=\"https:\/\/de.wikipedia.org\/wiki\/Minimax-Algorithmus\">Minimax-Algorithmus<\/a>? Hier sind die unterschiedlichsten Implementierungen denkbar.<\/p>\n<p>Machen wir f\u00fcr die zwei der drei genannten mal eine konkrete Implementierung.<\/p>\n<p>Aus Sicht des Clients ist nur eine Frage interessant: Wo in unserem 3&#215;3-Gitter soll das n\u00e4chste Symbol (also <strong>X<\/strong> oder <strong>O<\/strong>) gesetzt werden. Als Basis f\u00fcr diese Entscheidung erh\u00e4lt die Strategie den aktuellen Status des Spiels.<\/p>\n<p>Das dazugeh\u00f6rige Interface sieht entsprechend einfach aus:<\/p>\n<pre class=\"lang:java decode:true\">public interface MoveStrategy {\r\n\tint getNextPosition(GameState state);\r\n}<\/pre>\n<p>Schauen wir uns nun einmal die Implementierung f\u00fcr einen menschlichen Spieler an, der \u00fcber die Konsole seine Eingaben macht:<\/p>\n<pre class=\"\">public class HumanStrategy implements MoveStrategy {\r\n\r\n   public int getNextPosition(GameState state) {\r\n      String input;\r\n      Scanner in = new Scanner(System.in);\r\n      \r\n      do {\r\n         System.out.println(\"Bitte Zahl zwischen 1 und 9 f\u00fcr leeres Feld eingeben:\");\r\n         input = in.next();\r\n      } while (!inputValid(state, input));\r\n         \r\n      int position = Integer.parseInt(input);       \r\n      return position-1;\r\n   }\r\n\r\n   private boolean inputValid(GameState state, String input) {\r\n      [...]\r\n   }\r\n}<\/pre>\n<p>Es werden also so lange Zahlen zwischen 1-9 \u00fcber die Konsole abgefragt, bis ein g\u00fcltiger Wert f\u00fcr einen Zug eingegeben wurde. Dieser wird dann an den Client zur\u00fcckgegeben. Diese menschliche Strategie implementiert unser Interface.<\/p>\n<p>Als n\u00e4chstes schauen wir uns eine KI-Implementierung an, die das Symbol an eine zuf\u00e4llige Stelle im Spielfeld setzt:<\/p>\n<pre class=\"lang:java decode:true \">public class RandomStrategy implements MoveStrategy {\r\n\r\n\tpublic int getNextPosition(GameState state) {\t\t\t\t\r\n\t\tList&lt;Integer&gt; operators = state.getOperators();\r\n\r\n\t\tRandom randomGenerator = new Random();\r\n\t\tint result;\r\n\t\tdo {\r\n\t\t\tresult = operators.get(randomGenerator.nextInt(operators.size()));\r\n\t\t} while (!resultValid(state, result));\r\n\t\t\r\n\t        return result;\r\n\t}\r\n\r\n\tprivate boolean resultValid(GameState state, int result) {\r\n\t\treturn state.isEmptyAt(result - 1);\r\n\t}\r\n}\r\n<\/pre>\n<p>Auch diese ist von der Implementierung her denkbar einfach. Es werden zuf\u00e4llig Zahlen ermittelt, die auf G\u00fcltigkeit gepr\u00fcft und dann zur\u00fcckgegeben werden. Diese KI-Strategie implementiert ebenfalls unser Interface.<\/p>\n<p>Wie aber nutzen wir diese nun? Auch das ist ziemlich einfach:<\/p>\n<pre class=\"lang:java decode:true \">public class TicTacToe {\r\n\r\n    public void run() {\r\n        Player player1 = new Player(\"Player1\", \"X\", new HumanStrategy());\r\n        Player player2 = new Player(\"Player2\", \"O\", new RandomStrategy());\r\n        while(true) {\r\n            [...]\r\n\r\n            int nextPosition = player.determineNextMove(getGameState());\r\n\r\n            [...]\r\n        }\r\n    }\r\n}\r\n<\/pre>\n<p>Wir erstellen also unsere Spieler und \u00fcbergeben diesen &#8211; neben dem Namen und dem zu verwendenden Symbol &#8211; jeweils die passende Strategie.<\/p>\n<p>Im Spieler sieht das dann folgenderma\u00dfen aus:<\/p>\n<pre class=\"lang:java decode:true\">public class Player {\r\n    private String name;\r\n    private MoveStrategy strategy;\r\n    private String symbol;\r\n\r\n    [...]\r\n\r\n    public int getNextMove(GameState state) {\r\n        return this.strategy.getNextPosition(state);\r\n    }\r\n    [...]\r\n}<\/pre>\n<p>In der Methode getNextMove() des jeweiligen Spielers wird nun die entsprechende Strategie verwendet, die f\u00fcr den Spieler \u00fcbergeben wurde. Einfach, oder?<\/p>\n<p>An der Klasse Spieler m\u00fcssen wir also nichts \u00e4ndern, wenn wir eine neue Zug-Strategie implementieren m\u00f6chten.<\/p>\n<p>&nbsp;<\/p>\n<h1>Wann ist das Strategie-Muster sinnvoll anzuwenden?<\/h1>\n<p>Die Verwendung des Strategie-Musters bietet sich insbesondere dann an, wenn wir erst zur Laufzeit genau wissen, was wir eigentlich tun m\u00f6chten (etwa durch eine Konfiguration oder eine Laufzeitbedingung festgelegt).<br \/>\nAuch wenn wir unterschiedliche (austauschbare) Varianten eines Algorithmus nutzen m\u00f6chten, bietet es sich an, diesen als Strategie an die verarbeitende Klasse zu \u00fcbergeben, statt alles doppelt zu implementieren.<\/p>\n<p>Wollen wir Wiederverwendbare Klassen schaffen, ist das Strategie-Muster oft eine gute, leicht zu implementierende L\u00f6sung. Ein <a href=\"http:\/\/invidit.de\/blog\/was-riecht-hier-so\/\">Code-Smell<\/a>, bei dem man \u00fcberlegen k\u00f6nnte, das Strategie-Muster anzuwenden sind eine gro\u00dfe Anzahl von Verzweigungen im Code (if-else-if-else-if, switch-case). Statt die Entscheidung in der implementierenden Klasse zu treffen, kann der Ausf\u00fchrungsteil einfach \u00fcbergeben werden. Die Entscheidung erfolgt dann au\u00dferhalb, was die Klasse selbst vor Ver\u00e4nderungen sch\u00fctzt.<\/p>\n<p>&nbsp;<\/p>\n<h1>Zusammenfassung?<\/h1>\n<p>Mit dem Strategie-Muster steht uns ein m\u00e4chtiges, leicht zu verstehendes und leicht zu implementierendes Muster zur Verf\u00fcgung um unseren Code sauber zu machen und Abh\u00e4ngigkeiten klar voneinander zu trennen. Eine Strategie hilft bei der Umsetzung der meisten SOLID-Prinzipien.<\/p>\n<p>Lediglich die Auswahl der richtigen Strategie zur Laufzeit kann zu einem Problem f\u00fchren, das diese Aufgabe nun in den Client verlagert wird. Wichtig ist auch, dass man sich beim Einsatz einer Vielzahl von Strategien f\u00fcr ein gut strukturiertes Ablage- und Namensschema entscheidet und dies auch einh\u00e4lt. Sonst kann der \u00dcberblick schnell verloren gehen.<\/p>\n<p>F\u00e4llt euch spontan eine Stelle ein, bei der euch das Muster h\u00e4tte helfen k\u00f6nnen? Wer mag, kann ja auch mal eine KI-Strategie nach dem <a href=\"https:\/\/de.wikipedia.org\/wiki\/Minimax-Algorithmus\">Minimax-Algorithmus<\/a> implementieren. Eine Musterl\u00f6sung gibt es unter Github (siehe unten).<\/p>\n<p>&nbsp;<\/p>\n<p>Wir w\u00fcnschen euch viel Spa\u00df beim Ausprobieren der unterschiedlichen Strategien.<\/p>\n<p>Eure Spa\u00df-Coder<\/p>\n<p>&nbsp;<\/p>\n<p>Dieser Artikel basiert neben unseren Erfahrungen auf den Ausf\u00fchrungen aus:<\/p>\n<ul>\n<li>http:\/\/www.duden.de\/rechtschreibung\/Strategie<\/li>\n<li>https:\/\/de.wikipedia.org\/wiki\/Strategie_%28Entwurfsmuster%29<\/li>\n<li>https:\/\/dzone.com\/articles\/design-patterns-strategy<\/li>\n<\/ul>\n<p>Code-Beispiele auf Github:<\/p>\n<ul>\n<li>https:\/\/github.com\/invidit\/CodeQuality\/tree\/master\/TicTacToe<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Hallo Spa\u00df-Coder. Mit einem weiteren Thema aus unserer Reihe \u00fcber Entwurfsmuster geht es nun munter weiter. Wir werden uns nun einmal mit einem Mustern aus der Kategorie der Verhaltensmuster besch\u00e4ftigen. Wir schauen uns in diesem Artikel das Strategie-Muster (engl. Strategy Pattern) an, ebenfalls aus der Sammlung der Gang of Four. &nbsp; Was ist denn das, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":1092,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[90],"tags":[130,140,34,142],"_links":{"self":[{"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/posts\/1086"}],"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\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/comments?post=1086"}],"version-history":[{"count":16,"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/posts\/1086\/revisions"}],"predecessor-version":[{"id":1106,"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/posts\/1086\/revisions\/1106"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/media\/1092"}],"wp:attachment":[{"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/media?parent=1086"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/categories?post=1086"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/invidit.de\/blog\/wp-json\/wp\/v2\/tags?post=1086"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}