Search
Tento domácí úkol se týká témat: UML, návrhový vzor Adaptér, Template Method a drobné opakování na Git a práci s null hodnotami.
Vaše společnost implementuje systém umožňující provádět platby pomocí platební brány. Dlouhou dobu systém fungoval vůči starému rozhraní, které poskytovala platební brána. Dodavatel platební brány vydal novou verzi, kterou by Váš systém měl začít podporovat. Zároveň poměrně rozsáhlá část Vašeho řešení závisí na původní verzi.
Váš kolega dostal za úkol rozšířit existující systém o podporu nové platební brány. Váš kolega neprošel předmětem OMO a proto výsledek můžete vidět v Merge Requestu, který pro Vás připravil k revizi:
https://gitlab.fel.cvut.cz/B231_B6B36OMO/hw02_internal/-/merge_requests/1
Zkuste si položit následující otázky:
Na základě konzultace s kolegy přijdete s novým návrhem, jak systém upravit tak, aby splňoval vlastnosti správného návrhu.
Při návrhu využijete hned několik postupů a návrhových vzorů. Hlavním z návrhových vzorů je takzvaný Adaptér. Ve zkratce vytvoříme pro každou verzi platební brány samostatnou třídu.
Třída by neměla míchat metody, třídní proměnné ani konstruktory specifické pro danou verzi. Z kolegova návrhu není na první pohled jasné čím se jednotlivé verze liší a co mají společné.
Rozdělením jednotlivých verzí platební brány do samostatných tříd / adaptérů bude jasně vidět, čím se dané verze liší. Tím že každý adaptér bude dědit od jedné abstraktní třídy a/nebo implementovat jedno společné rozhraní je zřejmé co mají třídy společné.
Aby třída fungovala pro více verzí, tak typicky často duplikuje opakující se kusy kódu. Vezměte si například následující:
if (useModernGateway) { // DO something for modern gateway } else { // DO something for legacy gateway }
Když třída musí podporovat různé nekompatibilní verze, tak bude málokdy jednoduchá a čitelná.
Vaším cílem je implementovat systém dle následujícího UML Class Diagramu:
Dále je nutné dodržet strukturu projektu dle následujících názvů Java packages:
Refactoring je často iterativní, v zadání sice máte již hotové zadání, k tomu často ale dojdete postupně.
Například při tomto příkladu by šlo postupovat následovně:
Při refaktoringu si také všimnete, že metoda executeTransaction() sestává pro obě verze ze shodných kroků:
Použijeme tedy návrhový vzor, který se jmenuje Template Method a který nám umožní pomocí abstraktních metod vytvořit ,,předpis'' pro metodu executeTransaction() a implementaci jednotlivých kroků necháme na potomcích.
Protože si všimnete, že kolega také trochu nebezpečně pracuje s null hodnotami a víte, jak dokáže takový NullPointerException potrápit. (Zvláště u nováčků je to jedna ze základních chyb a měli byste se na ni proto zaměřit již při code review).
Proto se snažíme psát defensivní kód a pracujeme raději s Java 8 Optional, než s null referencemi. Upravíme tedy i odpovídajícím způsobem kolegův kód.
Odezvdávejte prosím pouze třídy z balíčku cz.cvut.fel.omo.homeworks.refactor.transaction v .zip souboru zbytek tříd odevzdávací systém již obsahuje.