Wzorzec metody szablonowej
Część sekcji Programowanie obiektowe ścieżki C# w Coddy. Lekcja 59 z 70.
Wzorzec Template Method to wzorzec behawioralny, który definiuje szkielet algorytmu w klasie bazowej, umożliwiając podklasom nadpisywanie określonych kroków bez zmieniania ogólnej struktury. Klasa bazowa kontroluje przepływ pracy, a klasy pochodne dostosowują poszczególne elementy.
Ten wzorzec wykorzystuje dziedziczenie i metody abstrakcyjne. Klasa bazowa zawiera „metodę szablonową”, która wywołuje sekwencję kroków, z których niektóre są abstrakcyjne i muszą zostać zaimplementowane przez podklasy:
public abstract class DataProcessor
{
// Metoda szablonowa - określa strukturę algorytmu
public void Process()
{
ReadData();
ProcessData();
SaveData();
}
protected abstract void ReadData();
protected abstract void ProcessData();
protected virtual void SaveData() => Console.WriteLine("Saving to default location");
}
public class CsvProcessor : DataProcessor
{
protected override void ReadData() => Console.WriteLine("Reading CSV file");
protected override void ProcessData() => Console.WriteLine("Parsing CSV data");
}
public class JsonProcessor : DataProcessor
{
protected override void ReadData() => Console.WriteLine("Reading JSON file");
protected override void ProcessData() => Console.WriteLine("Parsing JSON data");
protected override void SaveData() => Console.WriteLine("Saving to cloud");
}Każda podklasa zapewnia własną implementację, a klasa bazowa wymusza kolejność operacji:
DataProcessor csv = new CsvProcessor();
csv.Process();
// Odczytywanie pliku CSV
// Parsowanie danych CSV
// Zapisywanie w domyślnej lokalizacji
DataProcessor json = new JsonProcessor();
json.Process();
// Odczytywanie pliku JSON
// Parsowanie danych JSON
// Zapisywanie w chmurzeWzorzec Template Method sprawdza się idealnie, gdy wiele klas ma tę samą strukturę algorytmu, ale różni się poszczególnymi krokami. Ułatwia ponowne wykorzystanie kodu, umieszczając wspólną logikę w klasie bazowej, a jednocześnie zapewnia elastyczność dzięki metodom, które można przesłaniać.
Wyzwanie
ŁatwyZbudujmy system generowania raportów z użyciem wzorca Metody Szablonowej. Różne typy raportów (takie jak raporty sprzedaży i raporty magazynowe) mają tę samą ogólną strukturę — wszystkie muszą zebrać dane, sformatować je i wyświetlić wynik — ale każdy typ raportu obsługuje te kroki inaczej.
Rozmieścisz swój kod w trzech plikach:
ReportGenerator.cs: Utwórz abstrakcyjną klasęReportGeneratorw przestrzeni nazwReporting. Ta klasa bazowa definiuje szkielet algorytmu generowania raportów za pomocą metody szablonowej o nazwieGenerate(). Metoda powinna wywołać trzy kroki w podanej kolejności:GatherData(),FormatReport()iOutputReport(). OznaczGatherData()iFormatReport()jako abstrakcyjne (każdy typ raportu zaimplementuje je inaczej), natomiastOutputReport()powinna być metodą wirtualną z domyślną implementacją, która wyświetlaSending to default printer.ConcreteReports.cs: Utwórz w tej samej przestrzeni nazw dwie konkretne klasy raportów dziedziczące poReportGenerator:SalesReport— implementujeGatherData(), aby wyświetlaćCollecting sales data from database, orazFormatReport(), aby wyświetlaćFormatting as sales summaryInventoryReport— implementujeGatherData(), aby wyświetlaćScanning warehouse inventory,FormatReport(), aby wyświetlaćFormatting as inventory list, oraz nadpisujeOutputReport(), aby wyświetlaćSending to warehouse manager
Program.cs: Połącz wszystkie elementy, tworząc instancje raportów i generując je. Metoda szablonowa sprawia, że każdy raport przechodzi ten sam trzyetapowy proces, ale konkretne zachowanie każdego kroku zależy od typu raportu.
Otrzymasz jedno wejście:
- Typ raportu:
saleslubinventory
Utwórz odpowiedni generator raportów na podstawie wejścia i wywołaj jego metodę Generate().
Na przykład, jeśli wejściem jest sales, wyjście powinno wyglądać następująco:
Collecting sales data from database
Formatting as sales summary
Sending to default printerJeśli wejściem jest inventory, wyjście powinno wyglądać następująco:
Scanning warehouse inventory
Formatting as inventory list
Sending to warehouse managerZwróć uwagę, że oba raporty korzystają z dokładnie tej samej struktury algorytmu (zbieranie, formatowanie, wyświetlanie), ale implementacja każdego kroku jest dostosowana do potrzeb. SalesReport korzysta z domyślnego zachowania wyświetlania, natomiast InventoryReport je nadpisuje — pokazuje to, jak wzorzec Metody Szablonowej pozwala określić, które kroki trzeba nadpisać, a które można dostosować opcjonalnie!
Spróbuj swoich sił
using System;
using Reporting;
class Program
{
public static void Main(string[] args)
{
string reportType = Console.ReadLine();
// TODO: Utwórz odpowiedni generator raportu na podstawie reportType
// Jeśli reportType ma wartość "sales", utwórz SalesReport
// Jeśli reportType ma wartość "inventory", utwórz InventoryReport
// Następnie wywołaj metodę Generate() dla raportu
}
}
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Programowanie obiektowe
1Podstawy programowania obiektowego
Pliki zewnętrznePrzestrzenie nazw i dyrektywyWprowadzenie do klas i obiektówSłowo kluczowe „this”Metody i parametryPola a właściwościKonstruktoryInicjalizatory obiektówPodsumowanie — prosty kalkulator4Dziedziczenie
Podstawowa składnia dziedziczenia (:)Słowo kluczowe 'base'Słowa kluczowe virtual i overrideKlasy sealedBazowa klasa 'object'Powtórzenie – hierarchia pracowników7Zaawansowane funkcje
Przeciążanie operatorówIndeksery (this[])Nadpisywanie ToString()Metody rozszerzającePodsumowanie – własna lista2Właściwości i składowe statyczne
Właściwości automatyczneWłaściwości tylko do odczytu i zapisuPola i metody statyczneKlasy statyczneSkładowe z ciałem wyrażeniowym5Polimorfizm i interfejsy
Polimorfizm czasu kompilacji a czasu wykonaniaInterfejs a klasa abstrakcyjnaWiele interfejsówJawne implementowanie interfejsówRzutowanie w górę i w dółPowtórka — kalkulator kształtów8Zaawansowane koncepcje OOP
Kompozycja zamiast dziedziczeniaTypy generyczne (klasy i metody)Delegaty i zdarzeniaAtrybuty i refleksjaIDisposable i instrukcja usingPodstawy wstrzykiwania zależności11Wzorce projektowe, część 2
Wzorzec poleceniaWzorzec adapteraWzorzec dekoratoraWzorzec metody szablonowejWzorzec stanuWzorzec kompozytu3Architektura klas
Dane instancji a dane statyczneSłowa kluczowe 'readonly' i 'const'Pola zapasowePowtórzenie — menedżer kont bankowych6Hermetyzacja
Modyfikatory dostępuWłaściwości w hermetyzacjiImplementacja ukrywania danychWzorce niezmiennościPowtórka — dane studentów9Argumenty zmiennej liczby
Słowo kluczowe „params”Parametry opcjonalneArgumenty nazwanePrzeciążanie metodPoćwicz samodzielnie: Kompilator C# online