Ich weiß, dass dies eine alte Frage ist, aber ich denke, ich habe ein weiteres interessantes Beispiel, das ich kürzlich implementiert habe.
Dies ist ein sehr praktisches Beispiel für das Strategiemuster, das in einem Dokumentenlieferungssystem verwendet wird.
Ich hatte ein PDF-Liefersystem, das ein Archiv mit vielen Dokumenten und einigen Metadaten erhielt. Basierend auf den Metadaten wurde entschieden, wo das Dokument abgelegt werden soll. sagen wir, abhängig von den Daten, konnte ich das Dokument in speichern A
, B
oder C
Speichersysteme, oder eine Mischung der drei.
Verschiedene Kunden verwendeten dieses System und hatten im Falle von Fehlern unterschiedliche Anforderungen an die Rollback- / Fehlerbehandlung: Man wollte, dass das Liefersystem beim ersten Fehler stoppt, alle bereits gelieferten Dokumente in ihren Lagern belässt, den Prozess jedoch stoppt und nichts anderes liefert ;; Ein anderer wollte, dass es B
bei Fehlern beim Speichern zurückgesetzt wird C
, aber alles, was bereits geliefert wurde, belässt A
. Es ist leicht vorstellbar, dass ein dritter oder vierter auch andere Bedürfnisse haben wird.
Um das Problem zu lösen, habe ich eine grundlegende Übermittlungsklasse erstellt, die die Übermittlungslogik sowie Methoden zum Zurücksetzen von Daten aus allen Speichern enthält. Diese Methoden werden vom Liefersystem im Fehlerfall nicht direkt aufgerufen. Stattdessen verwendet die Klasse Dependency Injection, um eine "Rollback / Error Handling Strategy" -Klasse (basierend auf dem Kunden, der das System verwendet) zu erhalten, die im Fehlerfall aufgerufen wird und die Rollback-Methoden aufruft, wenn dies für diese Strategie geeignet ist.
Die Übermittlungsklasse selbst meldet, was in der Strategieklasse vor sich geht (welche Dokumente an welche Speicher geliefert wurden und welche Fehler aufgetreten sind), und fragt bei jedem Fehler die Strategie, ob sie fortfahren soll oder nicht. Wenn in der Strategie "stop it" angegeben ist, ruft die Klasse die "cleanUp" -Methode der Strategie auf, die anhand der zuvor gemeldeten Informationen entscheidet, welche Rollback-Methoden von der Übermittlungsklasse aufgerufen werden sollen, oder einfach nichts unternimmt.
rollbackStrategy.reportSuccessA(...);
rollbackStrategy.reportFailureB(...);
if (rollbackStrategy.mustAbort()) {
rollbackStrategy.rollback(); // rollback whatever is needed based on reports
return false;
}
Ich habe jetzt zwei verschiedene Strategien: eine ist die QuitterStrategy
(die beim ersten Fehler beendet wird und nichts bereinigt) und die andere ist die MaximizeDeliveryToAStrategy
(die so viel wie möglich versucht, den Prozess nicht abzubrechen und niemals an den Speicher gelieferte Inhalte zurückzusetzen A
, aber Rollbacks von, B
wenn die Lieferung C
fehlschlägt).
Nach meinem Verständnis ist dies ein Beispiel für das Strategiemuster. Wenn Sie (ja, Sie lesen) denken, dass ich falsch liege, kommentieren Sie bitte unten und lassen Sie es mich wissen. Ich bin gespannt, was eine "reine" Verwendung des Strategiemusters bedeuten würde und welche Aspekte meiner Implementierung gegen die Definition verstoßen. Ich finde es ein bisschen lustig, weil die Strategie-Oberfläche ein bisschen fett ist. Alle Beispiele, die ich bisher gesehen habe, verwenden nur eine Methode, aber ich denke immer noch, dass dies einen Algorithmus einschließt (wenn ein Teil der Geschäftslogik als Algorithmus betrachtet werden kann, was meiner Meinung nach auch so ist).
Da die Strategie auch während der Ausführungsausführung über Ereignisse informiert wird, kann sie auch als Beobachter betrachtet werden , aber das ist eine andere Geschichte.
Nach ein wenig Recherche scheint es sich um ein "zusammengesetztes Muster" zu handeln (wie MVC, ein Muster, das auf besondere Weise mehrere darunter liegende Entwurfsmuster verwendet), das als Advisor bezeichnet wird . Es ist ein Ratgeber, ob die Lieferung fortgesetzt werden soll oder nicht, aber es ist auch ein aktiver Fehlerbehandler, da es auf Anfrage Rollbacks durchführen kann.
Wie auch immer, dies ist ein ziemlich komplexes Beispiel, das Ihnen das Gefühl geben könnte, dass die Verwendung des Strategiemusters allzu einfach / albern ist. Es kann sehr komplex und noch anwendbarer sein, wenn es zusammen mit anderen Mustern verwendet wird.