Dataniedziela, 9 sierpnia 2026 Czas08:05:20
← Programowanie konsolowe (C#)

Lekcja 18. Wzorce projektowe — Metoda szablonowa, Fasada, Kompozyt

Trudny / egzaminacyjny

Po co się tego uczymy?

Wzorce projektowe to sygnał dla oceniającego (nauczyciela, egzaminatora, przyszłego pracodawcy), że rozumiesz nie tylko SKŁADNIĘ C#, ale też jak dobrze ORGANIZOWAĆ kod w większych projektach — to wiedza, która odróżnia programistę piszącego działający kod od programisty piszącego kod, który da się później utrzymać i rozwijać.

Teoria

Wzorzec projektowy to SPRAWDZONE, nazwane rozwiązanie często powtarzającego się problemu projektowego — zamiast wymyślać rozwiązanie od zera, korzystasz z gotowego "przepisu", który wielu programistów przed Tobą uznało za dobry. Podstawa programowa wymienia wprost trzy wzorce, którymi zajmiemy się w tej lekcji.

Metoda szablonowa (Template Method) — klasa bazowa definiuje SZKIELET algorytmu (kolejność kroków), ale pozwala klasom pochodnym nadpisać POJEDYNCZE kroki, nie cały proces. To rozszerzenie tego, co już znasz z Lekcji 14-14 (metody wirtualne + klasy abstrakcyjne) — tutaj metoda "organizująca" jest zwykła (niewirtualna), a tylko poszczególne kroki wewnątrz są wirtualne/abstrakcyjne.

Fasada (Facade) — jedna, PROSTA klasa "ukrywająca" skomplikowaną współpracę wielu innych klas za wygodnym, czytelnym interfejsem. Użytkownik fasady nie musi wiedzieć, ile klas i jak dokładnie współpracuje pod spodem — woła jedną prostą metodę, a cała złożoność jest ukryta w środku.

Kompozyt (Composite) — pozwala traktować POJEDYNCZY obiekt i GRUPĘ obiektów w JEDNAKOWY sposób, przez wspólny interfejs/klasę bazową. Klasyczny przykład: folder w systemie plików może zawierać zarówno pojedyncze pliki, jak i inne foldery (które z kolei zawierają kolejne pliki/foldery) — a obliczenie "całkowitego rozmiaru" działa identycznie, niezależnie od tego, ile poziomów zagnieżdżenia ma struktura.

Wszystkie trzy wzorce bazują na tym, czego nauczyłeś się we wcześniejszych lekcjach (dziedziczenie, polimorfizm, hermetyzacja) — nie są nową składnią C#, tylko sposobem UKŁADANIA już znanych narzędzi w sprawdzony, powtarzalny sposób.

Przykład z życia

Pilot samolotu naciska jeden przycisk "autopilot" (fasada), nie martwiąc się dziesiątkami systemów, które ten jeden przycisk uruchamia pod spodem. Struktura folderów na Twoim komputerze to z kolei klasyczny kompozyt — folder może zawierać pliki i inne foldery, a "rozmiar folderu" liczy się tak samo niezależnie od głębokości zagnieżdżenia.

Kod (C#)

using System;

// --- METODA SZABLONOWA ---
abstract class PrzygotowanieRaportu
{
    // metoda szablonowa - definiuje STAŁĄ kolejność kroków
    public void Wykonaj()
    {
        PobierzDane();
        Przetworz();
        Zapisz();
    }

    protected abstract void PobierzDane();
    protected abstract void Przetworz();

    protected void Zapisz() // wspólny krok, ten sam dla wszystkich raportów
    {
        Console.WriteLine("Raport zapisany do pliku.");
    }
}

class RaportSprzedazy : PrzygotowanieRaportu
{
    protected override void PobierzDane() => Console.WriteLine("Pobieram dane sprzedaży...");
    protected override void Przetworz() => Console.WriteLine("Liczę sumy sprzedaży...");
}

// --- FASADA ---
class SilnikSerwisu
{
    public void SprawdzHaslo(string haslo) => Console.WriteLine("Sprawdzam hasło...");
    public void ZaladujProfil() => Console.WriteLine("Ładuję profil użytkownika...");
    public void ZapiszLogowanie() => Console.WriteLine("Zapisuję log logowania...");
}

class FasadaLogowania // ukrywa 3 osobne kroki za JEDNĄ prostą metodą
{
    private SilnikSerwisu silnik = new SilnikSerwisu();

    public void Zaloguj(string haslo)
    {
        silnik.SprawdzHaslo(haslo);
        silnik.ZaladujProfil();
        silnik.ZapiszLogowanie();
        Console.WriteLine("Zalogowano pomyślnie!");
    }
}

class Program
{
    static void Main()
    {
        PrzygotowanieRaportu raport = new RaportSprzedazy();
        raport.Wykonaj(); // ta sama kolejność kroków dla każdego raportu

        Console.WriteLine();

        FasadaLogowania logowanie = new FasadaLogowania();
        logowanie.Zaloguj("tajneHaslo123"); // jedno wywołanie zamiast trzech
    }
}

Komentarz i wyjaśnienie kodu

W metodzie szablonowej Wykonaj() NIE JEST wirtualna — jej kolejność kroków jest ZAWSZE taka sama dla każdego raportu. To poszczególne kroki (PobierzDane(), Przetworz()) są abstrakcyjne i różnią się w zależności od konkretnego typu raportu, podczas gdy Zapisz() jest wspólny dla wszystkich. W fasadzie klasa FasadaLogowania "chowa" przed użytkownikiem trzy osobne kroki logowania za jedną metodą Zaloguj() — użytkownik fasady nie musi wiedzieć, że w środku dzieje się aż tyle.

Ćwiczenie samodzielne

Dodaj do przykładu z lekcji drugą klasę pochodną RaportMagazynu : PrzygotowanieRaportu z własną implementacją PobierzDane() i Przetworz().

Plac zabaw — wypróbuj online

Poniższy kod wykonuje się od razu w Twojej przeglądarce — nic nie trzeba instalować. Zmień kod i kliknij „Uruchom”.

CSHARP

Zadania do pracy własnej

  1. Zbuduj prostą fasadę FasadaZamowienia ukrywającą trzy osobne kroki (sprawdzenie stanu magazynu, obciążenie karty, wysłanie potwierdzenia e-mail — wszystkie jako osobne metody wypisujące tekst) za jedną metodą ZlozZamowienie().

  2. Zbuduj metodę szablonową dla procesu "przygotowania posiłku" (klasa abstrakcyjna Przepis z metodą Ugotuj() wywołującą po kolei PrzygotujSkladniki(), Gotuj() i wspólny krok Podaj()), i dwie klasy pochodne dla różnych potraw.

  3. Zbuduj uproszczony wzorzec Kompozyt dla struktury plików: wspólny interfejs IElementPliku z metodą int RozmiarKB(), klasa Plik (implementuje bezpośrednio, zwraca swój rozmiar) i klasa Folder (przechowuje List<IElementPliku> i zwraca SUMĘ rozmiarów wszystkich elementów — w tym zagnieżdżonych folderów). Zbuduj przykładową strukturę z folderami wewnątrz folderów i oblicz łączny rozmiar całości JEDNYM wywołaniem.

Typowe błędy

Częsty błąd to mylenie metody szablonowej ze zwykłym polimorfizmem (Lekcja 14) — kluczowa różnica to to, że metoda ORGANIZUJĄCA kolejność kroków (Wykonaj()) NIE jest nadpisywana, tylko POSZCZEGÓLNE kroki wewnątrz niej. Drugi błąd: fasada, która sama zawiera dużo logiki zamiast tylko DELEGOWAĆ pracę do innych klas — fasada ma być cienką, prostą warstwą "na wierzchu", nie kolejną skomplikowaną klasą. Trzeci: implementacja Kompozytu bez wspólnego interfejsu/klasy bazowej dla "pojedynczego elementu" i "grupy elementów" — bez tego nie da się traktować ich jednakowo, co jest całym sensem tego wzorca.

Nawiązanie do egzaminu zawodowego

To bezpośrednia, dosłowna realizacja efektu INF.04.3.8 z podstawy programowej: "stosuje wzorce projektowe" — oficjalny tekst wymienia wprost jako przykłady "Metodę szablonową, Fasadę, Kompozyt", dokładnie te trzy wzorce omówione w tej lekcji.