- Dodałem 3 interfejsy i 3 klasy implementujące je. Przeprowadziłem zmiany w innych klasach, tak aby wszystko działało
Brawo! W ten sposób zaimplementowałeś właśnie wzorzec repozytorium - tak jak polecałem na początku ;-)
Możesz teraz dumnie zmienić nazwę Storage
na Repository
, a przestrzeń nazw DB
na Repositories
.
Btw, nie ma sensu trzymać interfejsów w dodatkowej przestrzeni CarRentalInterfaces
- mogą być wszystkie obok siebie.
- Klasy służy temu, abyw klasie
CarRentalEngine
nie było tzw. "magic numbers".
Nie są to "magic numbers", jeśli kilka linijek wyżej wprost pytasz użytkownika Wpisz 1, aby uruchomić ...
.
- Aczkolwiek zastanawia mnie po co jest to
this.
Faktycznie - teraz zauważyłem, że Ty akurat nie wykorzystujesz this.
- jeden rabin powie tak, inny powie inaczej.
W tym wypadku rzeczywiście, trzymając się konwencji, powinno się obejść bez tego.
- Nie są lokalnymi z tego względu, że w niektórych przypadkach są używane w wielu metodach przez co wydawało mi się bez sensu tworzyć w każdej metodzie tego samego jak można raz to zrobić.
Nah, raczej takiego patentu się nie wykorzystuje:
- Sprawiasz, że Twoja klasa przestaje być
thread-safe
(jeden wątek może nadpisać zapytanie drugiemu - gdybyś korzystał ze zmiennych lokalnych, nie byłoby tego problemu),
- Zyskujesz kilka bajtów, w zamian utrudniając JVM analizę i optymalizację swojego kodu - przez to, że zapisujesz obiekt zapytania do pola klasy (a nie zmiennej lokalnej),
garbage collector
nie może się tego zapytania pozbyć (usunąć z pamięci) do momentu, do którego go nie nadpiszesz następnym (co w przypadku tak małej aplikacji nie stanowi żadnego problemu, lecz mogłoby zacząć w przypadku większych).
- Zyskujesz kilka bajtów, w zamian utrudniając innym ludziom analizę swojego kodu - na samym początku nie zauważyłem wcale, że jest to pole klasy i tak przyglądałem się temu kodowi myśląc
od kiedy w javie można pominąć deklarację zmiennej
.
- Tutaj nie rozumiem, jakie id?
Poczytaj o podstawach projektowania baz danych, ze szczególnym zwróceniem uwagi na to, czym różni się klucz podstawowy (primary key
) od klucza złożonego (composite key
) oraz czym różni się klucz naturalny (natural key
) od klucza sztucznego (surrogate key
). Nie jest to czarna magia, a znacznie uprości też kod w paru miejscach.
Ad 12: testy wydają się teraz spoko :-)
- Chodziło Ci o coś takiego?
Prawie - zauważ, że Twoje klasy DataBaseCommunication
i CarRentalOptions
są zależne od konkretnej implementacji: wymagają ona podania jej repozytoriów MySQLowych i nawet gdybyś miał zaimplementowane inne, Twoje klasy tego nie przyjmą.
Porównaj to z takim podejściem: https://4programmers.net/Pastebin/9356
Mógłbyś mieć np. MySQLCarStorage
, FileCarStorage
, InMemoryCarStorage
i nieskończenie wiele innych... i dla każdej możliwej implementacji Twoja klasa będzie działać bez jakiejkolwiek zmiany! :-)
Fachowo nazywa się to dependency inversion principle
- też polecam rzucić okiem w wolnej chwili.
Nie musisz od razu rzucać się na głębokie morze i uczyć sposobu działania konkretnych implementacji DI w Javie - poczytaj i zrozum, na czym polega ten pattern, tyle wystarczy.
- Szczerze powiedziawszy skupia ona wszystkie możliwości jakie posiada ten program. W wyniku czego łatwiej mi jest się posługiwać metodami w CarRentalEngine. Wydaje mi się, że wygląda to estetyczniej.
Ok, czyli jest to realizacja wzorca fasada
- fine with me ;-)
Jeżeli miałbym usunąć tę klasę, to gdzieś musiałbym przenieść te 3 metody:
Te metody za dużo nie robią - nie potrzeba tworzyć dla nich od razu odrębnej klasy.
Tym niemniej nie ma źle - IMO może zostać tak, jak jest.