Frameworki i biblioteki w kwalifikacji INF.04: najważniejsze zasady, przykłady i 42 powiązane pytania w banku.
Framework nie jest większą biblioteką. To gotowy szkielet aplikacji: narzuca układ katalogów, cykl życia żądania i punkty, w których wolno dopisać własny kod. Za tę wygodę płaci się częścią kontroli nad przepływem sterowania, więc wybór między biblioteką a frameworkiem jest decyzją projektową, a nie kwestią gustu. W zadaniach z INF.04 trzeba zwykle rozpoznać, kto kogo wywołuje, gdzie trafia logika biznesowa i który plik odpowiada za zależności projektu.
Biblioteka, framework i odwrócenie sterowania
Bibliotekę wywołujesz ty: importujesz funkcję sortującą i sam decydujesz, w której linii ją uruchomić. Framework wywołuje twój kod: rejestrujesz kontroler pod ścieżką albo obsługę zdarzenia, a moment uruchomienia wybiera silnik frameworka. Ta zamiana kierunku nosi nazwę odwrócenia sterowania, znanego też jako zasada Hollywood.
Dlatego React opisuje się jako bibliotekę do budowy interfejsu: routing i klienta HTTP trzeba dobrać osobno, na przykład React Router. Angular jest frameworkiem, bo w komplecie daje router, wstrzykiwanie zależności, klienta HTTP i wymuszony układ katalogów przez własne narzędzie wiersza poleceń. Tę samą rolę pełnią WPF i JavaFX na desktopie, Flutter oraz Jetpack Compose na urządzeniach mobilnych, a po stronie serwera Django, Laravel i Spring Boot.
MVC i MVVM: kto trzyma stan, a kto rysuje
W MVC żądanie trafia do kontrolera. Kontroler odczytuje lub zmienia dane w modelu, a potem wskazuje widok, który ma je wyświetlić. Widok nie sięga do bazy, a model nie wie, czy wynik trafi do HTML, czy do JSON. Uwaga na nazewnictwo: Django nazywa swój wzorzec MTV, więc funkcja pełniąca rolę kontrolera nazywa się tam widokiem, a szablon odpowiada widokowi z MVC.
MVVM zastępuje kontroler warstwą ViewModel i wiązaniem danych. ViewModel wystawia właściwości, na przykład czyLaduje i listaZadan, oraz zgłasza ich zmiany, więc kontrolka odświeża się sama, bez ręcznego przypisywania tekstu. ViewModel nie zna klasy okna ani kontrolek, dzięki czemu da się go przetestować bez uruchamiania interfejsu. Wzorzec ten spotkasz w WPF, w Avalonii i w warstwie ViewModel na Androidzie.
ORM zamienia wiersz tabeli w obiekt
Mapowanie obiektowo-relacyjne łączy tabelę z klasą, kolumnę z polem, a pojedynczy wiersz z instancją. Klucz obcy staje się referencją: zamiast pisać JOIN, odczytujesz zamowienie.klient.nazwisko, a ORM w tle wykonuje potrzebne zapytanie. Wartości trafiają do zapytania jako parametry, co domyślnie zamyka drogę do wstrzyknięcia SQL, ale ochrona znika, gdy sam sklejasz surowy SQL z tekstu wpisanego przez użytkownika.
Ceną wygody jest pułapka N+1, wynikająca z leniwego doczytywania powiązań. Pobranie 50 zamówień to jedno zapytanie, lecz odczyt klienta w pętli dokłada 50 kolejnych, razem 51. Wymuszenie pobrania powiązanych danych z góry sprowadza to do jednego lub dwóch zapytań: w Django służy do tego selectrelated i prefetchrelated, w SQLAlchemy joinedload i selectinload, w Eloquent metoda with, a w JPQL zapis JOIN FETCH. Dlatego przy ORM trzeba zaglądać do logu wykonanych zapytań.
Plik zależności, plik blokady i wersjonowanie semantyczne
Plik zależności mówi, czego projekt wymaga: npm czyta package.json, Composer czyta composer.json, a w Pythonie tę rolę pełni requirements.txt albo pyproject.toml. Plik blokady zapisuje dokładne wersje całego drzewa zależności wraz z sumami kontrolnymi; są to package-lock.json, composer.lock oraz poetry.lock lub uv.lock. Polecenie npm ci instaluje wyłącznie to, co stoi w blokadzie, więc dwa komputery dostają identyczny zestaw bibliotek. Blokada należy do repozytorium, katalog node_modules nie, bo można go odtworzyć w każdej chwili.
Wersja semantyczna ma postać GŁÓWNA.POBOCZNA.POPRAWKA. Poprawka błędu zmienia 2.4.1 w 2.4.2, zgodna wstecz nowa funkcja daje 2.5.0, a zmiana łamiąca API daje 3.0.0. Zapis ^2.4.1 dopuszcza wszystko od 2.4.1 do wersji mniejszej niż 3.0.0, a ~2.4.1 tylko do wersji mniejszej niż 2.5.0. Wyjątkiem są wydania przed jedynką: dla ^0.2.3 npm podnosi wersję najwyżej do 0.2.x, bo w gałęzi 0.x każda zmiana pobocznej może łamać API.
Testy w projekcie opartym na frameworku
Test jednostkowy sprawdza jedną klasę bez bazy i sieci, a zależność podmieniasz atrapą, na przykład repozytorium zwracającym ustaloną listę trzech rekordów. Test integracyjny uruchamia prawdziwy stos: framework daje klienta testowego, taki jak Client w Django, TestClient w FastAPI czy metoda get w testach Laravela, który wysyła żądanie do trasy i pozwala sprawdzić kod odpowiedzi oraz treść JSON.
Pojedynczy test składa się z trzech kroków nazywanych przygotowaniem, wykonaniem i sprawdzeniem. Testów jednostkowych pisze się najwięcej, bo trwają milisekundy, a integracyjnych mniej, bo wymagają bazy, choćby SQLite w pamięci; trzeba wtedy pamiętać, że SQLite inaczej niż PostgreSQL traktuje typy i ograniczenia, więc część błędów wyjdzie dopiero na docelowym silniku. Test bez asercji albo zależny od kolejności uruchomienia daje złudne poczucie bezpieczeństwa.
Kiedy framework dokłada zbędnej złożoności
Framework zwraca się w projekcie, który ma być utrzymywany przez lata: routing, walidacja, migracje bazy, sesje i uwierzytelnianie są już napisane i poprawiane przez wielu programistów, a nowa osoba w zespole zastaje znaną konwencję. Dochodzi do tego przewidywalny cykl wydań, na przykład Django publikuje wersję funkcjonalną mniej więcej co osiem miesięcy, a co trzecia z nich jest oznaczona jako LTS i ma trzy lata wsparcia. Przy skrypcie na 150 linii, który raz w tygodniu przetwarza plik CSV, ten sam zestaw to głównie koszt nauki i aktualizacji.
Sygnałem nadmiaru bywa strona wizytówka ładująca kilkaset kilobajtów JavaScriptu tam, gdzie wystarczy statyczny HTML, trzy warstwy abstrakcji nad jednym zapytaniem SQL albo plik konfiguracyjny dłuższy od logiki. Decyzję podejmij, porównując czas wdrożenia i utrzymania, łącznie z przejściem na kolejną wersję główną i podmianą porzuconych zależności, z czasem napisania tej samej funkcji ręcznie.
Z tym działem powiązano 42 pytania w banku INF.04. Na ekranie Wszystkie pytania wybierz jeden z tagów: frameworki. Możesz wtedy przejrzeć zadania tylko z interesującego Cię obszaru.