Pracuję nad aplikacją, której moduł wykonuje kolejno następujące operacje finansowe:
Gdy użytkownik poprosi o przelanie określonej kwoty na swoje konto bankowe:
- sprawdzić, czy jakaś transakcja może się teraz zdarzyć? (transakcja może być przeprowadzona tylko przez określony czas)
- sprawdź, czy użytkownik zażądał wypłaty minimalnej kwoty
- sprawdź, czy użytkownik ma jakieś domyślne konto
Wynik wszystkich powyższych działań powinien zostać zarejestrowany.
Jeśli wszystkie powyższe warunki zostaną spełnione, transakcja zostanie przeprowadzona. W przyszłości mogą pojawić się dodatkowe kontrole.
Który wzór obiektowy powinien najlepiej pasować do powyższego przypadku?
Odpowiedzi:
Wygląda na to, że to, czego szukasz, to łańcuch odpowiedzialności . W takim przypadku możesz mieć następujące klasy:
TransactionValidatorBase
abstrakcyjna klasa podstawowaTransactionTimeValidator
TransactionAmountValidator
TransactionAccountValidator
Są one połączone razem, aby zastosować dowolną liczbę określonych reguł.
Furter Reading
źródło
Jeśli sekwencja kroków polega głównie na sprawdzaniu poprawności (tak, jak się wydaje), bez zmiany danych wejściowych, naprawdę pomyślałbym o wzorcu „łańcucha odpowiedzialności”, jak wyjaśniono w jego odpowiedzi przez @pswg
Ale ponieważ twoje pytanie jest nieco bardziej ogólne, chciałbym również dodać „przetwarzanie potokowe”, ponieważ w tym przypadku krok wytworzyłby dane wyjściowe, które stałyby się danymi wejściowymi dla następnego kroku (w ten sposób mutując oryginalne dane wejściowe) .
Oto dwa artykuły na ten temat:
Kolekcja rurociągów autorstwa Martina Fowlera
Więcej teoretycznych dyskusji na temat wzoru
źródło
Prawidłowy wzorzec tutaj naprawdę zależy od kontekstu. Przed wybraniem konkretnego wzoru, którego będę się trzymać, postaram się znaleźć odpowiedzi na te pytania:
Opierając się na przeczuciu, kodowałbym je jako proste metody z agregującym parametrem dla kodów błędów.
Dobrym pomysłem może być umieszczenie DoTransaction w interfejsie „ITransactionValidationStragegy” i utworzenie nadtypu warstwy, który będzie zawierał sprawdzający kod sprawdzania poprawności.
Jednak w tym projekcie zakładam, że logika sprawdzania poprawności jest ustalana w czasie kompilacji.
źródło
Chociaż wzorce są już tutaj wspomniane, sugerowałbym, abyś pomyślał o tym, jak chciałbyś użyć tego samego w swojej aplikacji, w oparciu o używane ramy.
Na przykład walidacja, którą chcesz wykonać, najprawdopodobniej będzie się zmieniać wraz z upływem czasu (może być konieczne dodanie nowej walidacji w przyszłości, która ogranicza transakcje do 10 dziennie). Ponadto może nie być konieczne sprawdzanie poprawności przed uruchomieniem faktycznej usługi biznesowej lub kodu integracji. Byłoby dobrze, gdyby można było dodać sprawdzania poprawności jako konfigurowalne.
Jeśli używasz Struts, dobrym pomysłem może być użycie przechwytywaczy. W przypadku wiosny zastrzyk fasoli jako zależność daje większą elastyczność. Moją sugestią jest nie tylko przyjrzenie się wzorcom / idiomom, ale także przyjrzenie się ramom, których używasz do zbudowania aplikacji, i zobaczenie, jak najlepiej możesz dopasować się do swoich wymagań z futurystycznego punktu widzenia.
źródło
Według mojego zrozumienia, wszystko, co jest wymagane, można dopasować do wzorca poleceń, jak poniżej. Projektowanie klas można wykonać zgodnie z poniższym opisem.
Twoja klasa klienta będzie zawierać następujący fragment kodu:
Zgodnie z moim zrozumieniem scenariusz ten został podany powyżej.
źródło