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
Prościej, wygodniej i szybciej. Tak teraz pracuję na komputerze
ChatGPT wpadł w pułapkę? Jest kłopot z rozwiązaniem problemu Naviera-Stokesa
Za co naprawdę płacimy, kupując słuchawki premium? Wyjaśniamy na przykładzie Bowers & Wilkins Px7 S3
Recenzja Forever Ago. Piękna opowieść z nudną rozgrywką
Wielka tajemnica psów rozwiązana. Od zawsze było to zagadką czworonogów
Ten banan ciemnieje znacznie wolniej. Zmienili jego DNA
Zapłacisz kartą nawet bez internetu i prądu. Zmiany obejmą też Polskę
Rewolucja w PS5. Sony wprowadza nową zakładkę
Do garażu, kanapy i kominka. Parkside ma odkurzacz na każdą okazję
Kara za olewanie aktualizacji. Twój smartfon może być zagrożony
Wystarczy jeden zły sterownik. Microsoft wyjaśnia problemy Windowsa 11
Microsoft wywraca XBOX do góry nogami. Gry to dopiero początek
iPhone po cichu zużywa dane? Wyłącz to
Google otwiera SynthID Detector — tak sprawdzisz, czy treść stworzyła AI
Jedenaście dni na jednym ładowaniu. Huawei Watch 6 300 zł taniej w promocji premierowej
Huawei stawia wszystko na aparaty. Nowe Pura 90s Pro i Pro Max już w Polsce!
Tanio już było. Produkty z Chin mogą być jeszcze droższe
Powstanie film w uniwersum Cyberpunk 2077. Na pokładzie Paramount i... CD Projekt!
Zdjęcie z sieci doprowadziło do wielkiego odkrycia
Uruchomił GTA V w przeglądarce. To serio działa
O powstawaniu kamieni drogą doboru naturalnego
Świat upomina się o „właściwe” proporcje
Kosmiczna panorama i superkoronograf – co przyniesie nam Teleskop Nancy Roman?
O czym szepczą między sobą bozony Higgsa?
Wszechświat w trzech aktach – recenzja książki “Astronomia, kosmologia i astronautyka”
Wielka przerwa Wielkiego Zderzacza
A gdyby tak przeciąć foton na pół?
SpudCell – syntetyczna komórka, która udaje życie
Mega upał, omega manipulacja
Coraz więcej dowodów, coraz mniej pewności
Wyglądają i grają jak premium, a kosztują ułamek tej ceny. Recenzja Baseus Inspire XH1
WRZESIEŃ BĘDZIE MOCNY… Premiery gier, na które czekamy – Mamy do pogrania
Całkiem dobry film ten nowy Spider-Man: Brand New Day 🕷️ – No Movie Ci #18
Scyzorykon 2026, Galaxy Fold8 i całkiem nowy Spider-Man – Odcinek #137
Sprawdziliśmy Scyzorykon 2026 od środka!
Co się działo na Fantasy & Magic Con w Warszawie?
Porozmawiajmy o Steam Machine 🎮👀
Przedsprzedaż GTA VI, Stargate i gry, które paliły sprzęty – Odcinek #136
Relacja z CD-Action Expo 2026
Tańszy Game Pass, droższy Steam Deck i Internet 0202122 – Odcinek #135

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.