IT-Academy Logo
Sign Up Login Help
Home - Programmieren - Entwurfsmuster: Strategy



Entwurfsmuster: Strategy

Dieser Artikel beschreibt eines der einfachsten Entwurfsmuster; das Verhaltensmuster "Strategy".


Autor: Patrick Bucher (paedubucher)
Datum: 03-06-2007, 21:31:23
Referenzen: Entwurfsmuster von Kopf bis Fuss, Freeman und Freeman, O'Reilly-Verlag, jetzt bei Amazon.de kaufen
Schwierigkeit: Fortgeschrittene
Ansichten: 10673x
Rating: Bisher keine Bewertung.

Hinweis:

Für den hier dargestellte Inhalt ist nicht der Betreiber der Plattform, sondern der jeweilige Autor verantwortlich.
Falls Sie Missbrauch vermuten, bitten wir Sie, uns unter missbrauch@it-academy.cc zu kontaktieren.

[Druckansicht] [Als E-Mail senden] [Kommentar verfassen]



Das Strategy-Muster definiert eine Familie von austauschbaren Algorithmen. Diese Algorithmen erfüllen gegen aussen einen ähnlichen Zweck, sie unterscheiden sich jedoch in ihrer Implementierung. Das Stragety-Muster wird verwendet, wenn:

  • ein Programm verschiedene Algorithmen für eine Aufgabe verwendet
  • das Verhalten von Algorithmen gekapselt werden soll
  • erst zur Laufzeit klar wird, welche Implementierung eines Algorithmus verwendet werden soll

Beim Strategy-Muster geht es somit immer um eine Familie von Algorithmen mit der gleichen Schnittstelle, die sich nur in ihrer Implementierung unterscheiden.

Aufbau

Es wird eine Schnittstelle definiert, welche die Definition aller unterstützten Algorithmen enthält. Diese Schnittstelle wird dann als "Strategie" bezeichnet. Die Algorithmen werden dann von verschiedenen Klassen implementiert, jede Implementierung der Strategie stellt eine "konkrete Strategie" dar.

Die konkreten Strategien werden dann von einem Kontext verwendet. Dieser ruft die Algorithmen jedoch nicht direkt, sondern über die Schnittstelle "Strategie" auf. Der Kontext stellt oftmals Methoden zur Verfügung, womit der Algorithmus ausgetauscht werden kann (z.B. durch setter-Methoden in Java). Die Referenz auf den konkreten Algorithmus wird dann im Kontext als Eigenschaft gespeichert.

Der Kontext wird immer von einem Klienten verwendet. Dieser ruft bestimmte Methoden auf dem Kontext auf. Dieser Aufruf wird dann innerhalb des Kontext weiter an die entsprechende konkrete Strategie delegiert.

Das ganze präsentiert sich dann folgendermassen als UML2-Klassendiagramm:

Definition

Das Strategy-Muster definiert eine Familie von Algorithmen, kapselt sie einzeln und macht sie austauschbar. Das Strategy-Muster ermöglicht es, den Algorithmus unabhängig von den Clients die ihn einsetzen, variieren zu lassen.

Implementierung

Für einen Taschenrechner sind verschiedene Rechenarten zu implementieren, unter anderem sind dies die Addition und die Subtraktion. Es sollen immer zwei Zahlen angegeben werden können, die Berechnung ergibt dann ein Resultat.

Die Schnittstelle der beiden Rechenarten Addition und Subtraktion ist somit gleich (es werden immer zwei Zahlen erwartet), der konkrete Algorithmus unterscheidet sich jedoch (bei der Addition sollen die Zahlen addiert werden, bei der Subtraktion soll die eine Zahl von der anderen subtrahiert werden). Somit müssen folgende Klassen und Schnittstellen erstellt werden:

  • Die Schnittstelle Berechnung
  • Die konkreten Strategien Addition und Subtraktion
  • Ein Taschenrechner als Kontext und ein Klient

Die Schnittstelle Berechnung

Die Schnittstelle Berechnung definiert eine einzige Methode, die Methode berechne(). Diese erwartet zwei ganzzahlige Werte.

(01)
(02)
(03)
(04)
(05)
(06)
package strategy;

public interface Berechnung
{
  public int berechne(int a, int b);
}

Die konkreten Strategien Addition und Subtraktion

Die beiden Klassen Addition und Subtraktion stellen die konkreten Strategien dar und implementieren somit die Schnittstelle Berechnung.

Die Klasse Addition:

(01)
(02)
(03)
(04)
(05)
(06)
(07)
(08)
(09)
package strategy;

public class Addition implements Berechnung
{
  public int berechne(int summandA, int summandB)
  {
    return summandA + summandB;
  }
}

Die Klasse Subtraktion:

(01)
(02)
(03)
(04)
(05)
(06)
(07)
(08)
(09)
package strategy;

public class Subtraktion implements Berechnung
{
  public int berechne(int minuend, int subtrahend)
  {
    return minuend + subtrahend;
  }
}

Diese beiden Klassen unterscheiden sich nur in ihrem Algorithmus; die Klasse Addition addiert die beiden Parameter während die Klasse Subtraktion den Wert des zweiten Parameters vom Wert des ersten Parameters subtrahiert. Das Resultat wird in beiden Fällen zurückgegeben.

Der Kontext Taschenrechner

Der Taschenrechner stellt den eigentlichen Kontext der Anwendung dar:

(01)
(02)
(03)
(04)
(05)
(06)
(07)
(08)
(09)
(10)
(11)
(12)
(13)
(14)
(15)
(16)
(17)
(18)
(19)
(20)
(21)
package strategy; 

public class Taschenrechner 
{ 
  private Berechnung rechenart; 

  public Taschenrechner() 
  { 
    rechenart = new Addition(); 
  } 

  public void setRechenart(Berechnung rechenart) 
  {
    this.rechenart = rechenart; 
  } 

  public int berechne(int a, int b) 
  { 
    return rechenart.berechne(a, b); 
  }
}

Die Klasse Taschenrechner verfügt über eine Eigenschaft namens rechenart des Typs Berechnung, diese ist auf Zeile (05) definiert.

Der Konstruktor belegt diese Eigenschaft mit der Rechenart Addition, dies geschieht auf Zeile (09). Es wird somit standardmässig die Addition verwendet. Der Algorithmus lässt sich doch mithilfe der Methode setRechenart() austauschen, diese ist von Zeile (12) bis und mit Zeile (15) definiert.

Mit der Methode berechne(), die auf den Zeilen (17) bis und mit (20) definiert ist, wird die eigentliche Berechnung durchgeführt. Die beiden Parameter werden dabei zur Berechnung an die jeweilige Rechenart delegiert, dieser Aufruf ist auf Zeile (19) ersichtlich.

Der Klient

Der Klient wird in diesem Beispiel mit der gleichnamigen Klasse Klient implementiert:

(01)
(02)
(03)
(04)
(05)
(06)
(07)
(08)
(09)
(10)
(11)
(12)
(13)
(14)
package strategy; 

public class Klient 
{ 
  public static void main(String[] args) 
  { 
    Taschenrechner rechner = new Taschenrechner();
    System.out.println(rechner.berechne(20, 15)); 

    // Wechsel der Strategie
    rechner.setRechenart(new Subtraktion());
    System.out.println(rechner.berechne(20, 15)); 
  } 
}

Die Klasse Klient enthält in diesem Fall die Methode main(), welche den Einstiegspunkt in unser Programm darstellt.

Auf Zeile (07) wird eine neue Instanz des Taschenrechners erstellt. Diese Instanz wird dann auf der Zeile (08) verwendet, hier soll eine Berechnung mit den beiden Zahlen 20 und 15 durchgeführt werden. Da der Konstruktor der Klasse Taschenrechner standardmässig die Addition als Berechnungsstrategie verwendet, lautet die Ausgabe 35.

Auf Zeile (11) wird diese Strategie jedoch verändert. Dazu wird eine neue Instanz der konkreten Strategie Subtraktion erstellt, welche dann dem Taschenrechner als neue Rechenart übergeben wird. Anschliessend wird erneut eine Berechnung mit den beiden Zahlen 20 und 15 durchgeführt. Da der Taschenrechner nun mit der Subtraktions-Strategie arbeitet, lautet das Ergebnis nun 5.

Vor- und Nachteile

  • Vorteile
    • Strategien stellen eine Alternative zur Bildung von Unterklassen dar.
      • Es wird Komposition und nicht Vererbung verwendet.
    • Die einzelnen Strategien verbessern die Wiederverwendung des Programmcodes.
    • Ähnliche Algorithmen werden in einer Familie von Algorithmen gruppiert.
    • Algorithmen können zur Laufzeit ausgetauscht werden.
      • Dies steigert die Flexibilität.
  • Nachteile
    • Klienten müssen die unterschiedlichen Strategien kennen.
      • Dies stellt eine feste Bindung zwischen Klienten und konkreten Strategien dar.
    • Es müssen sehr viele (kleine) Klassen implementiert werden.
    • Die Anzahl der Objekte zur Laufzeit wird erhöht.


[back to top]



Userdaten
User nicht eingeloggt

Gesamtranking
Werbung
Datenbankstand
Autoren:04503
Artikel:00815
Glossar:04116
News:13565
Userbeiträge:16551
Queueeinträge:06236
News Umfrage
Ihre Anforderungen an ein Online-Zeiterfassungs-Produkt?
Mobile Nutzung möglich (Ipone, Android)
Externe API Schnittstelle/Plugins dritter
Zeiterfassung meiner Mitarbeiter
Exportieren in CSV/XLS
Siehe Kommentar



[Results] | [Archiv] Votes: 1137
Comments: 0