Menu
Coddy logo textTech

Wzorzec metody szablonowej

Część sekcji Programowanie obiektowe ścieżki Java w Coddy. Lekcja 73 z 87.

Wzorzec metody szablonowej to behawioralny wzorzec projektowy, który definiuje szkielet algorytmu w klasie bazowej, umożliwiając podklasom nadpisywanie konkretnych kroków bez zmiany ogólnej struktury. Pomyśl o tym jak o przepisie: ogólny proces gotowania pozostaje taki sam, ale poszczególne składniki lub techniki mogą się różnić.

Wzorzec wykorzystuje klasę abstrakcyjną z metodą szablonową, która wywołuje sekwencję kroków. Niektóre kroki mają domyślne implementacje, podczas gdy inne są abstrakcyjne i muszą zostać zaimplementowane przez podklasy:

abstract class DataProcessor {
    // Metoda szablonowa - definiuje strukturę algorytmu
    public final void process() {
        readData();
        processData();
        saveData();
    }
    
    abstract void readData();
    abstract void processData();
    
    // Domyślna implementacja (metoda hakowa)
    void saveData() {
        System.out.println("Saving to default location");
    }
}

class CSVProcessor extends DataProcessor {
    void readData() {
        System.out.println("Reading CSV file");
    }
    
    void processData() {
        System.out.println("Parsing CSV data");
    }
}

class XMLProcessor extends DataProcessor {
    void readData() {
        System.out.println("Reading XML file");
    }
    
    void processData() {
        System.out.println("Parsing XML data");
    }
}

Metoda szablonowa jest zazwyczaj oznaczana jako final, aby zapobiec zmianie struktury algorytmu przez podklasy. Po wywołaniu wykonuje tę samą sekwencję dla wszystkich podklas:

DataProcessor csv = new CSVProcessor();
csv.process();
// Wynik:
// Odczytywanie pliku CSV
// Przetwarzanie danych CSV
// Zapisywanie w domyślnej lokalizacji

Wzorzec Metody Szablonowej sprawdza się idealnie, gdy masz algorytmy o tej samej strukturze, ale różniące się poszczególnymi krokami. Ułatwia ponowne wykorzystanie kodu, umieszczając wspólną logikę w klasie bazowej i umożliwiając dostosowywanie jej za pomocą dziedziczenia.

challenge icon

Wyzwanie

Łatwy

Zbudujmy system generowania dokumentów z użyciem wzorca metody szablonowej! Utworzysz strukturę, w której różne typy dokumentów (raporty i faktury) są generowane według tego samego procesu, ale poszczególne kroki są dostosowywane do ich typu. To idealne rozwiązanie w sytuacjach, gdy ogólny przepływ pracy jest stały, ale szczegóły różnią się w zależności od typu dokumentu.

Rozmieścisz kod w czterech plikach:

  • DocumentGenerator.java: Utwórz abstrakcyjną klasę bazową, która definiuje metodę szablonową. Twoja klasa DocumentGenerator powinna mieć:

    Metodę final o nazwie generateDocument(), która definiuje szkielet algorytmu, wywołując kolejno trzy kroki: createHeader(), createBody() i createFooter().

    Dwie metody abstrakcyjne: createHeader() i createBody(), które podklasy muszą zaimplementować.

    Metodę hakową createFooter() z domyślną implementacją, która wyświetla --- End of Document ---.

  • ReportGenerator.java: Utwórz konkretną podklasę do generowania raportów. Jej konstruktor powinien przyjmować tytuł raportu (String).

    Metoda createHeader() wyświetla === REPORT: [title] ===

    Metoda createBody() wyświetla Report content goes here...

    Użyj odziedziczonej domyślnej stopki.

  • InvoiceGenerator.java: Utwórz kolejną konkretną podklasę do generowania faktur. Jej konstruktor powinien przyjmować nazwę klienta (String) i kwotę (double).

    Metoda createHeader() wyświetla *** INVOICE ***

    Metoda createBody() wyświetla Customer: [name] w jednym wierszu, a następnie Amount Due: $[amount] w kolejnym wierszu (sformatuj kwotę do dwóch miejsc po przecinku).

    Nadpisz metodę createFooter(), aby wyświetlała Thank you for your business!

  • Main.java: Połącz elementy systemu metody szablonowej! Otrzymasz trzy dane wejściowe: tytuł raportu (String), nazwę klienta (String) i kwotę faktury (double).

    Utwórz obiekt ReportGenerator z tytułem i wywołaj generateDocument(). Wyświetl pusty wiersz jako separator. Następnie utwórz obiekt InvoiceGenerator z nazwą klienta i kwotą, po czym wywołaj generateDocument().

Otrzymasz kolejno trzy dane wejściowe: tytuł raportu (String), nazwę klienta (String) i kwotę faktury (double).

Na przykład dla danych wejściowych Q4 Sales, Acme Corp i 1500.00 wynik będzie następujący:

=== REPORT: Q4 Sales ===
Report content goes here...
--- End of Document ---

*** INVOICE ***
Customer: Acme Corp
Amount Due: $1500.00
Thank you for your business!

Zwróć uwagę, że oba typy dokumentów są generowane według tego samego, zdefiniowanego w metodzie szablonowej procesu składającego się z trzech kroków, ale każdy z nich dostosowuje te kroki inaczej. Klasa ReportGenerator korzysta z domyślnej stopki, a klasa InvoiceGenerator dostarcza własną. Na tym polega siła metod hakowych we wzorcu metody szablonowej!

Spróbuj swoich sił

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Wczytaj dane wejściowe
        String reportTitle = scanner.nextLine();
        String customerName = scanner.nextLine();
        double invoiceAmount = scanner.nextDouble();
        
        // TODO: Utwórz ReportGenerator z tytułem i wywołaj generateDocument()
        
        // TODO: Wypisz pustą linię jako separator
        
        // TODO: Utwórz InvoiceGenerator z nazwą klienta i kwotą, a następnie wywołaj generateDocument()
        
    }
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator Java online