Ich arbeite an einer Anwendung, deren Modul die folgenden Finanzoperationen nacheinander ausführt:
Wenn ein Benutzer die Überweisung eines bestimmten Betrags auf sein Bankkonto anfordert:
- Überprüfen Sie, ob jetzt eine Transaktion stattfinden kann. (Transaktion kann nur während eines bestimmten Zeitraums durchgeführt werden)
- Überprüfen Sie, ob der Benutzer die Abhebung eines Mindestbetrags beantragt hat
- Überprüfen Sie, ob der Benutzer über ein Standardkonto verfügt
Das Ergebnis aller oben genannten Aktionen sollte protokolliert werden.
Wenn alle oben genannten Bedingungen erfüllt sind, wird die Transaktion ausgeführt. In Zukunft könnte es einige zusätzliche Überprüfungen geben.
Welches objektorientierte Entwurfsmuster sollte für den obigen Fall am besten geeignet sein?
Antworten:
Es klingt so, als ob Sie nach einer Kette von Verantwortung suchen . In diesem Fall könnten Sie die folgenden Klassen haben:
TransactionValidatorBase
abstrakte BasisklasseTransactionTimeValidator
TransactionAmountValidator
TransactionAccountValidator
Diese sind verkettet, um die von Ihnen angegebenen Regeln anzuwenden.
Weiteres Lesen
quelle
Das richtige Muster hängt hier wirklich von einem Kontext ab. Bevor ich ein bestimmtes Muster auswähle, werde ich versuchen, Antworten auf diese Fragen zu finden:
Basierend auf einem Bauchgefühl würde ich sie als einfache Methoden mit aggregierenden Parametern für Fehlercodes codieren.
Es ist möglicherweise eine gute Idee, DoTransaction in die Schnittstelle "ITransactionValidationStragegy" einzufügen und einen Layer-Supertyp zu erstellen, der Validierungs-Boilerplate-Code enthält.
Bei diesem Entwurf gehe ich jedoch davon aus, dass die Validierungslogik zur Kompilierungszeit bestimmt wird.
quelle
Wenn Ihre Abfolge von Schritten hauptsächlich Validierungsaufgaben erfüllt (wie es aussieht), ohne die Eingaben zu mutieren, würde ich in der Tat an das Muster "Chain of Responsibility" denken, wie in seiner Antwort von @pswg erläutert
Da Ihre Frage jedoch etwas allgemeiner ist, möchte ich auch die "Pipeline-Verarbeitung" hinzufügen, da bei diesem Schritt ein Schritt eine Ausgabe erzeugt, die zur Eingabe für den nächsten Schritt wird (wodurch die ursprüngliche Eingabe mutiert wird). .
Hier sind zwei Artikel darüber:
Pipeline-Sammlung von Martin Fowler
Weitere theoretische Diskussion über das Muster
quelle
Während die Muster hier bereits erwähnt sind, würde ich Ihnen empfehlen, darüber nachzudenken, wie Sie sie in Ihrer Anwendung verwenden möchten, basierend auf den von Ihnen verwendeten Frameworks.
Beispielsweise wird sich die Validierung, die Sie durchführen möchten, höchstwahrscheinlich im Laufe der Zeit ständig ändern (möglicherweise möchten Sie in Zukunft eine neue Validierung hinzufügen, die Transaktionen auf 10 pro Tag beschränkt). Möglicherweise möchten Sie die Validierung auch nicht durchführen, bevor Ihr eigentlicher Business Service oder Integrationscode aktiviert wird. Es wäre gut, wenn Sie die Validierungen als konfigurierbare hinzufügen könnten.
Wenn Sie Struts verwenden, ist die Verwendung von Interceptors möglicherweise eine gute Idee. Im Frühling bietet die Bohneninjektion als Abhängigkeit mehr Flexibilität. Mein Vorschlag ist, nicht nur die Muster / Redewendungen zu betrachten, sondern auch das Framework, mit dem Sie die Anwendung erstellen, und herauszufinden, wie Sie aus futuristischer Sicht am besten zu Ihren Anforderungen passen können.
quelle
Nach meinem Verständnis kann alles, was erforderlich ist, wie unten beschrieben in das Befehlsmuster eingepasst werden. Das Klassendesign kann wie folgt durchgeführt werden.
Ihre Client-Klasse enthält das folgende Code-Snippet:
Dies ist nach meinem Verständnis mit dem oben angegebenen Szenario.
quelle