So erstellen Sie einen Strategieentscheidungsmechanismus basierend auf den Ergebniskombinationen mehrerer Befehle in C #

8

Ich habe einen Rollback / Retry-Mechanismus mit dem Befehlsmuster und einem benutzerdefinierten Wiederholungsmechanismus mit den Eigenschaften RetryCount und timeout threshold als Eingabe erstellt (wie hier beschrieben Was ist der beste Weg zu Hinzufügen eines Wiederholungs- / Rollback-Mechanismus für Sync / Async-Aufgaben in C #? ). Ich habe auch das Polly-Framework ausprobiert und es ist großartig!

Nun möchte ich sie in eine Abstraktion einbinden. Ich könnte es als Befehlsplanmechanismus oder befehlsbasierten Entscheidungsmechanismus beschreiben.

Also, basierend auf den verschiedenen Kombinationen von Befehlsergebnissen muss ich entscheiden, welche der ausgeführten Befehle rückgängig gemacht werden und welche nicht (ich möchte die Möglichkeit anbieten, eine ReTry-Taste zu drücken und einige der Befehle nicht zurückgesetzt werden).

Diese Befehle sind in einigen Kategorien gruppiert und ich muss verschiedene Rollback-Strategien für die verschiedenen Gruppen und Befehle (basierend auf dem Ergebnis) durchführen. Irgendeine Art von unterschiedlichen Richtlinien würde hier stattfinden!

WICHTIG: Ich möchte IF/ELSE usw. vermeiden. Das Chain-of-responsibility-Muster würde mir helfen, aber ich weiß es NICHT und ich möchte wirklich Hilfe :

%Vor%

Eine andere Idee könnte Observables oder Event-Handler sein, aber die Frage ist, wie man sie benutzt (?). Oder verwenden Sie einfach eine Liste / einen Stapel / eine Warteschlange von Befehlen und überprüfen Sie diese Liste, um die nächste Schrittentscheidung (?) Zu treffen:

%Vor%

SZENARIEN

Schließlich können Sie sich zwanzig (20) Befehle vorstellen, die in vier (4) Kategorien gruppiert sind.

Szenario 1

  • Gruppe 1 Befehle (5) waren erfolgreich
  • Gruppe 2 Befehle 1 und 2 waren erfolgreich, aber Befehl 3 war FAILED . Befehl 4 und 5 nicht ausgeführt
  • Gruppe 3 nicht ausgeführt
  • Gruppe 4 nicht ausgeführt

Entscheidung 1

  • Rollback Kommandos 1 und 2 aus Gruppe 2 ABER nicht die ganze Gruppe 1 Befehle

Szenario 2

  • Gruppe 1 Befehle (5) waren erfolgreich
  • Gruppe 2 Befehle (5) waren erfolgreich
  • Gruppe 3 Befehle (5) waren erfolgreich
  • Gruppe 4 Befehle 1 - 4 waren erfolgreich ABER Befehl 5 war FEHLGESCHLAGEN

Entscheidung 2

  • Rollback aller Befehle aus allen Gruppen

Ich möchte mich leiten und mir mit CODE Beispielen in C # helfen.

    
Giannis Grivas 03.06.2016, 11:36
quelle

1 Antwort

9

Ich denke, Sie brauchen etwas wie MultiCommand Pattern. Es ist sehr gut in HeadFirst Design Patterns definiert.

Ich habe einen Entwurfsentwurf erstellt, mit dem Befehle flexibel verwaltet werden können. Das ist nicht die endgültige Entscheidung, sondern nur eine grobe Idee, die für das weitere Design verwendet werden könnte ... Also, los geht's:

Zuerst erstellen wir eine Schnittstelle für alle Befehle:

%Vor%

Rollback () Aktion wird den Befehl selbst abbrechen, während BatchRollback () alle Stapel abhängiger Befehle abbrechen wird.

Zweitens erstellen wir eine abstrakte BaseCommand -Klasse mit einfacher Execute () und Rollback () Methodenimplementierung:

%Vor%

Beachten Sie, dass wir auch ein Template-Methode -Muster verwendet haben: Die Execute () - Methode der Basisklasse implementiert die Basislogik für die Befehlsausführung und Rollback. während die spezifische Aktion jedes Befehls in der Methode ExecuteAction () der untergeordneten Klassen implementiert wird.

Sehen Sie sich den BaseCommand -Konstruktor an: Er akzeptiert die MultiCommand -Klasse als Parameter, der die Liste der zu rollierenden Befehle speichert Während der Ausführung geht etwas schief.

Hier ist MultiCommand Klassenimplementierung:

%Vor%

Nun, unsere Befehle werden so aussehen:

%Vor%

Der Einfachheit halber habe ich Command2 , Command3 , Command4 genauso implementiert wie Command1 . Dann habe ich für fehlgeschlagene Befehlssimulation diese erstellt:

%Vor%

Versuchen wir, all diese Mitarbeiter zu benutzen: Szenario 1:

%Vor%

Wie Sie sehen, haben wir einige Befehle erstellt und sie in Gruppen verschoben (Gruppen sind Multicommands , die beliebig verschachtelt werden können).

Dann haben wir group1 und group2 in die Variable group gedrückt, um alle Befehle wie eins zu verwenden. Wir haben auch in den Konstruktor Command3 und FailCommand hineingeschoben Liste von Befehlen, die zurückgesetzt werden sollen, wenn mit ihnen etwas schief geht. Im Beispiel wird unser Befehl3 gut ausgeführt, aber Befehl4 schlägt fehl. Daher erwarten wir, dass command4 , command3 , command2 , command1 nach einem Fehler abgebrochen werden.

Hier ist die Ausgabe des Tests:

%Vor%

Szenario 2 Fast dasselbe wie Szenario 1 , aber hier möchten wir nur command3 und command1 zurücksetzen, falls command3 fehlschlägt:

%Vor%

Die Ausgabe ist hier:

%Vor%

Ich hoffe, es wird in Ihrer Situation nützlich sein ... Sie finden dieses Beispiel auf GitHub .

In den letzten Commits finden Sie eine flexiblere Version dieses Ansatzes

    
Johnny Svarog 04.06.2016, 15:19
quelle

Tags und Links