Skip to content

Witaj w Świecie Jutra!

  • Technologie jutra
  • Sprzęt jutra
  • Aplikacje jutra
  • Programowanie
  • Księga Drogi
  • Renowacja
  • Różności
  • Archiwum
  • Autor
  • Home
  • Wszystko
  • Wzorce projektowe – MVC
  • Programowanie
  • Wszystko

Wzorce projektowe – MVC

Jakub Raczkowski 3 lutego 2024

Obraz wygenerowany (Bing AI) - Tak uroczo głupi, że nie mogłem się powstrzymać.

Wreszcie udało nam się dotrzeć do końca serii wpisów na temat popularnych wzorców projektowych. Na ostatek zostawiłem coś ekstra – nie tyle wzorzec co prawdziwy schemat architektury oprogramowania: Model-View-Controller.

Z MVC przyszło mi korzystać już kilka razy, najpierw na kursie CodeGym, gdzie po prostu wykonywałem polecenia i nie za bardzo wiedziałem co, jak i dlaczego. Następnie przy pracy nad moim pierwszym samodzielnym projektem – tam już starałem się świadomie postępować zgodnie z regułami schematu, chociaż jeszcze nie do końca rozumiałem jak on działa.

Pora to zmienić.

Ogólny koncept MVC to podzielenie projektu na 3 części: Model, Widok i Kontroler. Pierwsza odpowiada za logikę, druga za wyświetlanie treści, a trzecia za przechwytywanie poleceń użytkownika.

Piękno tego rozwiązania polega na tym, że te elementy są bardzo luźno ze sobą połączone. Jeden Model można zastąpić innym, byleby miał to samo API. Może on korzystać z kilku różnych Widoków i mieć więcej niż jeden Kontroler. To sprawia, że nad każdym z tych modułów może pracować osobny zespół.

Nie dajcie się zwieść – Model to nie warstwa wizualna, ale logika oprogramowania.

Powyżej opisałem wam klasyczny schemat MVC, który wciąż jest w użyciu, ale raczej wśród amatorskiego oprogramowania. Jego następca: „Model 2” został przystosowany do tworzenia aplikacji webowych, gdzie za widok odpowiada dział frontend operujący na plikach HTML. Kontroler stał się servletem, a Model podzielił się na część implementującą logikę oraz na bazy danych.

Ale i Model 2 został dość niedawno ulepszony za sprawą frameworku Spring MVC. Póki co wiem o nim zbyt mało, aby napisać cokolwiek ponad to, że uprasza i standaryzuje użycie MVC.

Za wygląd aplikacji odpowiada View – jest tworzony przez dział Frontend.

Podręcznik Rusz głową! nie oferuje definicji MVC, aczkolwiek z lektury rozdziału mu poświęconego można wyciągnąć kilka wniosków:

  • Zaczynamy od stworzenia klasy Model. To z niego Widok będzie brał dane do wyświetlenia.
  • Następnie tworzymy klasę Controller z modelem wstrzykniętym w konstruktor. Tenże konstruktor zajmuje się również tworzeniem klasy Widoku w oparciu o siebie i model.
  • MVC bazuje na wzorcu Obserwator – Model dziedziczy klasę Observerable, View i Controller implementują interfejs Observer.
  • Model „nic nie wie” o pozostałych klasach, dlatego nie możemy się odnosić do zmiennych i metod w Widoku czy Kontrolerze.
  • Każda klasa ma inne zadanie i tego należy się trzymać, np. nie umieszczajmy logiki w klasach należących do View.

Znając reguły pozostaje już tylko zobaczyć jak to się sprawdza w akcji.

Zadaniem kontrolera jest tylko i wyłącznie przechwytywanie akcji użytkownika i wysyłanie ich do modelu.

Ale po kolei…

Czego potrzeba aby stworzyć ekscytujący model walki w grze?

Pomijając oprawę graficzną i różnorodność skilli dochodzimy do prostego szablonu przypominającego zasadami grę Kamień/Papier/Nożyce. Koniec końców musimy odgadnąć intencje przeciwnika i przygotować się na jego ruch. Kiedy się odsłoni – szybko atakujemy, kiedy on atakuje – my się bronimy, kiedy szykuje finala przed którym nie uchroni nas tarcza – staramy się uciec poza zasięg rażenia.

Czasami te zależności są bardziej złożone, ale reguła jest ta sama. Źródło obrazka.

To wszystko sprowadza się do jednego wspólnego mianownika:

Losowość

Jeśli wiemy, że z każdym ciosem zadajemy przeciwnikowi tyle a tyle obrażeń, a on nam tyle, że co trzeci atak jest zasłaniany tarczą, a co piąty zadaje podwójny „demydż”… Gra szybko przestaje bawić, a staje się pracą domową z matematyki.

Kiedy jednak wprowadzimy randomizację tych ruchów: nie każdy atak dosięgnie celu, nie każdy blok będzie udany, to już mamy namiastkę fajnej zabawy. A jak dodamy tam jeszcze zarządzanie zasobami takimi jak punkty życia, mana czy stamina to choćby warstwa wizualna odstraszała, program i tak znajdzie swoich zapaleńców próbujących różnych taktyk.

Starając się pokazać wzorzec MVC w działaniu stworzyłem prostą minigierkę, gdzie próbujemy przewidzieć ruchy przeciwnika i przyjąć postawę obronną kiedy ten atakuje, lub samemu napierać, gdy wróg nic nie robi. Na program składają się cztery klasy: Model, View, Controller oraz Main, której zadaniem jest tylko odpalenie gry.

Spójrzmy najpierw co się dzieje w konsoli:

Próbujemy odgadnąć co zrobi przeciwnik

Zasady są proste – patrzymy na szansę czy przeciwnik zaatakuje, jeśli jest spora to wpisujemy „block„. Gdy faktycznie wróg miał zadać cios to zostanie on automatycznie zablokowany. Ale jeśli nic nie chciał robić, a my zdecydowaliśmy się blokować, to wtedy i tak zaatakuje – tego ciosu nie zablokujemy, ale zada nam tylko połowę normalnych obrażeń.

Gdy natomiast wpiszemy „hit” i wróg atakuje, to my odniesiemy obrażenia, a on nie (przyjmijmy, że ma dłuższy oręż: wali z dzidy 😉 ). W przypadku kiedy atakujemy, a wróg nic nie planuje – tylko on odnosi obrażenia.

Możemy również wpisać jakiekolwiek inne słowo – zostanie to potraktowane jako komenda „wait” czyli nikt nikogo nie atakuje, ale szansa na atak przeciwnika zostaje przetasowana.

A jak ma się to do naszego MVC?

Klasa Controller

Działanie programu rozpoczyna się w klasie kontrolera. Jego konstruktor tworzy View (który od razu wyświetla: „Wpisz 'hit’ jeśli chcesz zaatakować lub 'block’ jeśli chcesz przygotować obronę.”), a następnie ręcznie (z poziomu metody main()) inicjalizujemy inputCommand() która czeka na wpisanie frazy przez gracza. Po wciśnięciu Enter pałeczka przechodzi do modelu:

model.processCommand(reader.readLine());

Następnie w klasie Model dzieje się cała magia związana z przetwarzaniem polecenia:

Klasa Model

Metoda processCommand() nie tylko wylicza wynik starcia, ale też powiadamia o tym obserwatorów: klasy Controller i View. W naszym przykładzie kontroler nie potrzebuje tej informacji, ale to zależy od implementacji. Za to Widok od razu bierze się za wyświetlanie nowych elementów, które pobiera z getterów Modelu:

Klasa View

Odpalenie całości to tylko kilka komend w metodzie main – utworzenie Modelu, następnie Kontrolera i dodanie obserwatorów:

Model model = new Model();
Controller controller = new Controller(model);
View view = controller.getView();

model.addObserver(controller);
model.addObserver(view);

controller.inputCommand();

I gotowe! Wszystkie zasady poprawnego użycia wzorca zostały zachowane: każda klasa uprawia tylko swoje poletko, każda może być zastąpiona inną. Równie dobrze mogę stworzyć nowy kontroler obsługujący kliknięcia myszką i nowy widok w Swingu, gdzie zamiast wpisywać tekst będę klikał na przycisk „Hit” albo „Block”. Mogę dodać nowy model, który inaczej wyliczy szansę na blok i atak – byleby tylko gettery się zgadzały.

Podsumowanie

W tym miejscu kończymy zabawę ze wzorcami projektowymi. Właśnie doczytuję ostatnie strony podręcznika i już myślę nad pierwszymi etapami pracy nad moim drugim projektem (spokojnie, o tym też napiszę). Teraz jednak, pozostaje jeszcze odpowiedzieć na pytanie:

Czy warto się było uczyć tego wszystkiego?

Nie wiem. Jeszcze. Osobiście czuję się znacznie lepszym programistą – bardziej świadomym tego co robię i dlaczego akurat w ten sposób. Ale czy ta wiedza mi się przyda? Pierwsze odpowiedzi przyjdą w trakcie prac nad ITCandidateEvaluator’em – już wkrótce. Pomocnym może być tu również cytat z filmu „Alien vs Predator” (2004) do którego mam mały sentyment. Na pytanie jednej załogantki „Po co ci pistolet na wyprawie badawczej?” jej kolega odrzekł:

„Lepiej mieć i nie potrzebować niż na odwrót.”

Główna bohaterka filmu też wali z dzidy 😀

Na odchodnym chciałbym wszystkim polecić książki z serii Rusz głową! Jak do tej pory przeczytałem dwie, ale już ciągnie mnie do kolejnej („Rusz głową! SQL”) bo to nie tyle garść wartościowych informacji, co również ciekawa lektura, którą chce się przerobić do samego końca.

Tags: design patterns programming

Continue Reading

Previous: Wzorce projektowe – Chain of Responsibility
Next: ITCandidateEvaluator – Geneza

Related Stories

Mageege Moon104 – test niskoprofilowego mechanika
  • Sprzęt

Mageege Moon104 – test niskoprofilowego mechanika

11 marca 2025
Przebranżowienie cz.4
  • Programowanie

Przebranżowienie cz.4

27 lutego 2025
Smartfon Jutra
  • Sprzęt

Smartfon Jutra

15 lutego 2025

Ze świata

  • Antyweb
  • Kwantowo
  • Dwóch po dwóch
Gemini Pro w tanim abonamencie Google One. Do tego 200 GB w chmurze
Robot to narzędzie, nie towarzysz. Emocjonalne AI to ślepa uliczka
Epic Games rozgrzewa fanów mocnych wrażeń. W sam raz na zimowe wieczory
Składany iPhone już jesienią. Nowe informacje
Zepp Pay – te banki pozwalają płacić zegarkami Amazfit
PlayStation Plus poleca się na środek zimy. Nowe gry dla płacących więcej
ChatGPT wprowadza reklamy. Tak wyglądają w praktyce
Wielkie gwiazdy na pierwszych kadrach nowego serialu twórcy Yellowstone
Ten zestaw LEGO obudzi najlepsze wspomnienia
ChatGPT stał się jeszcze lepszy. Oto nowy i do tego tani plan
Karta SIM bez rejestracji - czy to jeszcze możliwe i… czy ma sens?
Koniec balu. O te karty NVIDII będzie trudniej na rynku. Dużo trudniej
Dowiedz się jak AI pomaga w nauce! clickON to bezpłatne warsztaty nie tylko dla najmłodszych
Napakowana lista nowości HBO Max. Przezabawna trylogia i wiele więcej
Jak stworzyć miasto przyjazne rowerom? Paryż mówi to jasno
Samsung zaskoczy swoich fanów. Przecieki odkrywają sekret nowych flagowców
Twórca ChatGPT coś kombinuje. Czym jest Projekt Agora?
Elon Musk nie ma powodu do radości. Użytkownicy zgłaszają problemy
Słucham tego zamiast książek i podcastów. Ty też powinieneś spróbować
ChatGPT z dużą nowością. Przyda się, jeżeli często korzystasz
To by było na tyle, jeśli chodzi o możliwość ugody
Ocalić od zapomnienia
Ostatni kwant
ALH 84001 – meteoryt, o którym mówiono nawet w Białym Domu
HESS zarejestrował kosmiczny elektron o niespotykanej energii [Phys. Rev. Lett.]
Matka ciemnej materii – recenzja biografii “Vera Rubin. Życie”
Satelita, który zerwał się ze smyczy
Wiadomość od Carla Sagana do przyszłych eksploratorów Marsa
Ile najdłużej może trwać zaćmienie Słońca?
Nowa największa liczba pierwsza ma ponad 41 milionów cyfr [GIMPS]
30 lat konsoli PlayStation – Odcinek #130
Omawiamy serię The Walking Dead (gość: Stary Gracz)
Nikt nie potrzebuje cienkich smartfonów – Odcinek #129
To ostatni dzwonek na kolekcjonowanie gier i filmów
Najlepsza relacja z PGA 2025 (Poznań Game Arena)
Bumblebee wśród klawiatur. Marvo Meqa 80W – recenzja
Pierwsze spotkanie z Omoda 7 Super Hybrid
Logitech MX Master 4, Wednesday, 1670 sezon 2 – Odcinek #128
Tani pad, który chciał być jak DualSense. Test Monka Contra GT-96
Secret Service i prasa komputerowa w Polsce – Odcinek #127

To może cię zainteresować:

Mageege Moon104 – test niskoprofilowego mechanika
  • Sprzęt

Mageege Moon104 – test niskoprofilowego mechanika

11 marca 2025
Przebranżowienie cz.4
  • Programowanie

Przebranżowienie cz.4

27 lutego 2025
Smartfon Jutra
  • Sprzęt

Smartfon Jutra

15 lutego 2025
Czym jest Swagger?
  • Programowanie

Czym jest Swagger?

22 lipca 2024
  • Technologie jutra
  • Sprzęt jutra
  • Aplikacje jutra
  • Programowanie
  • Księga Drogi
  • Renowacja
  • Różności
  • Archiwum
  • Autor
Copyright © All rights reserved. | DarkNews by AF themes.