- 1 Section
- 10 Lessons
- unbegrenzt
Strategy
Stell dir vor, du benutzt ein Navigationsgerät. Du gibst dein Ziel ein – und kannst wählen: schnellste Route, kürzeste Route, mit Maut oder ohne, zu Fuß, mit Fahrrad. Das Ziel bleibt gleich, die Strategie zur Berechnung wechselt. Das Gerät selbst weiß nicht, wie die Strategie intern funktioniert – es ruft nur berechneRoute(start, ziel) auf. Genau das ist das Strategy-Pattern (Verhaltensmuster): ein Verhalten / Algorithmus wird als austauschbares Objekt modelliert. Statt if-else-Kaskaden für jede Variante schreibst du jede Variante als eigene Klasse mit demselben Interface. Diese Lektion zeigt dir Strategy am klassischen Beispiel Sortier-Algorithmen, vergleicht alten und neuen Code und erklärt, wo das Pattern in der Java-Welt überall vorkommt.
1) Was Strategy macht – Sortierung live
Hier siehst du dasselbe Array mit verschiedenen Sortier-Strategien sortiert. Der aufrufende Code wäre immer derselbe: sorter.sortiere(array). Was sich ändert: welche Strategy-Instanz hinter sorter steckt. Wähl eine Strategie und klick „Sortieren":
2) Vorher / Nachher – Code-Vergleich
Der Code ohne Strategy ist eine if-else-Kette. Sie funktioniert kurz, wird aber bei jeder neuen Variante länger. Mit Strategy ist jede Variante eine eigene Klasse, der Aufrufer-Code bleibt unverändert:
RadixSort dazukommt: eine neue Klasse anlegen, fertig. Bei „ohne Pattern" hätten wir wieder ein else if in die Methode reingeschoben und alle Tests neu laufen lassen. Klassisches Open-Closed-Prinzip.3) Die drei Rollen im Strategy-Pattern
Wie alle GoF-Muster hat Strategy eine klare Rollenverteilung. Drei Beteiligte:
- Context (oben:
Sortierer): hält eine Referenz auf eine konkrete Strategy und ruft sie auf. Der Kunde benutzt nur den Context. - Strategy (Interface) (oben:
SortStrategy): definiert die gemeinsame Schnittstelle aller Algorithmen. - ConcreteStrategy (oben:
BubbleSort,InsertionSort, ...): die konkreten Implementierungen.
Wichtig für die UML-Darstellung: der Context hat eine Aggregation zur Strategy (gestrichelte Linie oder Diamant), nicht eine Vererbung. Die ConcreteStrategies erben / implementieren die Strategy.
4) Bekannte Anwendungen
Strategy ist eines der häufigsten Patterns überhaupt. Wo immer ein Algorithmus austauschbar sein soll, ist es eine erste Wahl. Beispiele:
- Komparator in Java:
list.sort(Comparator)– jeder Comparator ist eine Strategy. Vergleich nach Name, nach Alter, absteigend, ... - Java-Streams:
stream.filter(predicate)– das Prädikat ist eine Strategy. - Validierung: verschiedene Validatoren (E-Mail, IBAN, Telefonnummer) als Strategies hinter einem
Validator-Interface. - Verschlüsselung: bei Verschlüsselungs-Bibliotheken kann man zur Laufzeit AES, ChaCha20, DES auswählen – jeder Algorithmus ist eine Strategy.
- Routenplaner: Google Maps mit „schnellste / kürzeste / mit Maut / ohne Maut".
- Kompression: ZIP, GZip, BZip2 – verschiedene Kompressions-Strategies.
- Pricing: Standardpreis vs. Rabatt-Strategie für Premium-Kunden vs. Sonderpreis für Mitarbeiter.
5) Strategy mit Lambdas – moderne Variante
In modernen Sprachen ist Strategy oft kompakter: statt eine Klasse zu schreiben, übergibt man einfach eine Lambda-Funktion. Beispiel in Java:
| Klassisch (Klasse) | Mit Lambda |
|---|---|
list.sort(new ByAge()) | list.sort((a,b) -> a.age - b.age) |
Eigene Klasse ByAge implements Comparator | Inline definiert, kein Boilerplate |
Lambdas sind streng genommen Functional Interfaces – Interfaces mit genau einer Methode. Sie sind die kompakteste Form des Strategy-Patterns. In Python und JavaScript ist das noch einfacher, weil Funktionen dort First-Class-Citizens sind: list.sort(key=lambda x: x.age). Mehr in Lambda & Streams.
6) Strategy vs. State – häufige Verwechslung
Strategy und State haben strukturell dieselbe UML – Context + Interface + ConcreteImplementations. Trotzdem sind sie konzeptionell verschieden:
- Strategy: der Anwender wählt den Algorithmus aus. „Welcher Algorithmus soll für diese Aufgabe verwendet werden?" Wechsel passiert von außen.
- State: das Objekt selbst wechselt seinen Zustand abhängig von seinem inneren Verhalten. Eine Bestellung wechselt von „Entwurf" → „Bestellt" → „Geliefert" – die Zustände triggern den Wechsel.
In der Prüfung: wenn die Aufgabe sagt „der Benutzer kann auswählen" → Strategy. Wenn „das System wechselt automatisch" → State. Mehr Patterns in den nächsten Lektionen, insbesondere Decorator, mit dem Strategy teilweise konkurriert.
Zusammenfassung
Strategy (Verhaltensmuster) macht einen Algorithmus zur austauschbaren Klasse: Strategy-Interface definiert eine Operation, ConcreteStrategies implementieren sie, der Context hält eine Referenz und delegiert die Aufrufe. Vorteile: kein if-else-Wahnsinn mehr, jede Strategie ist eigenständig testbar, neue Varianten ändern bestehenden Code nicht (Open-Closed), Algorithmus kann zur Laufzeit gewechselt werden. Allgegenwärtig in Java: Comparator, Streams-Operationen, Validatoren, Kompression, Verschlüsselung. Moderne Sprachen kürzen Strategy mit Lambdas. Strukturell identisch mit dem State-Pattern – Unterschied: bei Strategy wählt der Anwender, bei State wechselt das Objekt selbst.
Verwandte Lektionen: Observer · Decorator · Factory · und mehrWeitere relevante LektionenWarum Entwurfsmuster?SOLID-PrinzipienPolymorphismusAbstrakte Klassen & InterfacesSortier-AlgorithmenLambda & StreamsSymmetrische Verschlüsselung
