Pattern Template Method
Fa parte della sezione Programmazione orientata agli oggetti del percorso C# di Coddy. Lezione 59 di 70.
Il pattern Template Method è un pattern comportamentale che definisce lo scheletro di un algoritmo in una classe base, consentendo alle sottoclassi di sovrascrivere passaggi specifici senza modificare la struttura complessiva. La classe base controlla il flusso di lavoro, mentre le classi derivate personalizzano le singole parti.
Questo schema usa l’ereditarietà e i metodi astratti. La classe base contiene un «metodo modello» che chiama una sequenza di passaggi, alcuni dei quali sono astratti e devono essere implementati dalle sottoclassi:
public abstract class DataProcessor
{
// Metodo template - definisce la struttura dell'algoritmo
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");
}Ogni sottoclasse fornisce la propria implementazione, mentre la classe base impone l'ordine delle operazioni:
DataProcessor csv = new CsvProcessor();
csv.Process();
// Lettura del file CSV
// Analisi dei dati CSV
// Salvataggio nella posizione predefinita
DataProcessor json = new JsonProcessor();
json.Process();
// Lettura del file JSON
// Analisi dei dati JSON
// Salvataggio nel cloudIl pattern Template Method è ideale quando più classi condividono la stessa struttura dell'algoritmo ma differiscono in passaggi specifici. Promuove il riutilizzo del codice collocando la logica comune nella classe base e consentendo al contempo flessibilità tramite metodi sovrascrivibili.
Sfida
FacileCostruiamo un sistema di generazione di report usando il pattern Template Method. Diversi tipi di report (come i report sulle vendite e i report sull'inventario) condividono la stessa struttura generale: tutti devono raccogliere i dati, formattarli e produrre il risultato, ma ogni tipo di report gestisce questi passaggi in modo diverso.
Organizzerai il codice in tre file:
ReportGenerator.cs: crea una classe astrattaReportGeneratornello spazio dei nomiReporting. Questa classe base definisce lo scheletro dell'algoritmo di generazione dei report tramite un metodo template chiamatoGenerate(). Il metodo deve chiamare tre passaggi, in ordine:GatherData(),FormatReport()eOutputReport(). RendiGatherData()eFormatReport()astratti (ogni tipo di report li implementerà in modo diverso), mentreOutputReport()deve essere un metodo virtuale con un'implementazione predefinita che stampaSending to default printer.ConcreteReports.cs: crea due classi concrete di report nello stesso spazio dei nomi, che ereditano daReportGenerator:SalesReport- implementaGatherData()per stampareCollecting sales data from databaseeFormatReport()per stampareFormatting as sales summaryInventoryReport- implementaGatherData()per stampareScanning warehouse inventory,FormatReport()per stampareFormatting as inventory liste sovrascriveOutputReport()per stampareSending to warehouse manager
Program.cs: metti insieme tutti gli elementi creando istanze dei report e generandoli. Il metodo template garantisce che ogni report segua lo stesso processo in tre passaggi, ma il comportamento specifico di ogni passaggio varia in base al tipo di report.
Riceverai un input:
- Il tipo di report:
salesoinventory
Crea il generatore di report appropriato in base all'input e chiama il suo metodo Generate().
Per esempio, se l'input è sales, l'output dovrebbe essere:
Collecting sales data from database
Formatting as sales summary
Sending to default printerSe l'input è inventory, l'output dovrebbe essere:
Scanning warehouse inventory
Formatting as inventory list
Sending to warehouse managerNota come entrambi i report seguano esattamente la stessa struttura dell'algoritmo (raccolta, formattazione, output), ma l'implementazione di ciascun passaggio è personalizzata. SalesReport usa il comportamento di output predefinito, mentre InventoryReport lo sovrascrive: questo dimostra come il pattern Template Method ti permetta di controllare quali passaggi è obbligatorio sovrascrivere e quali possono essere personalizzati facoltativamente!
Provalo tu
using System;
using Reporting;
class Program
{
public static void Main(string[] args)
{
string reportType = Console.ReadLine();
// TODO: Crea il generatore di report appropriato in base a reportType
// Se reportType è "sales", crea un SalesReport
// Se reportType è "inventory", crea un InventoryReport
// Poi chiama il metodo Generate() sul report
}
}
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Programmazione orientata agli oggetti
1Fondamenti della programmazione orientata agli oggetti
File esterniNamespace e direttiveIntroduzione a classi e oggettiLa parola chiave "this"Metodi e parametriCampi e proprietàCostruttoriInizializzatori di oggettiRiepilogo - Calcolatrice semplice4Ereditarietà
Sintassi di base dell'ereditarietà (:)La parola chiave 'base'Parole chiave virtual e overrideClassi sealedLa classe base 'object'Riepilogo - Gerarchia dei dipendenti7Funzionalità avanzate
Sovraccarico degli operatoriIndicizzatori (this[])Override di ToString()Metodi di estensioneRiepilogo - Lista personalizzata10Pattern di progettazione Parte 1
Introduzione ai pattern di progettazioneSingleton thread-safePattern FactoryPattern Observer (eventi)Pattern Strategy2Proprietà e membri statici
Proprietà implementate automaticamenteProprietà di sola lettura e di sola scritturaCampi e metodi staticiClassi staticheMembri con corpo di espressione5Polimorfismo e interfacce
Polimorfismo a compile time e runtimeInterfaccia o classe astrattaInterfacce multipleInterfacce espliciteUpcasting e downcastingRipasso: calcolatore di forme8Concetti avanzati di programmazione a oggetti
Composizione invece dell'ereditarietàTipi generici (classi e metodi)Delegati ed eventiAttributi e reflectionIDisposable e istruzione usingNozioni di base sull'iniezione delle dipendenze11Pattern di progettazione, parte 2
Pattern del ComandoPattern dell’AdattatorePattern del DecoratorePattern Template MethodPattern dello StatoPattern Composito3Architettura delle classi
Dati di istanza vs staticiParole chiave 'readonly' e 'const'Campi di supportoRiepilogo - Gestore di conti bancari6Incapsulamento
Modificatori di accessoProprietà per l'incapsulamentoImplementazione dell'occultamento dei datiModelli di immutabilitàRiepilogo - Registri degli studentiEsercitati da solo: Compilatore C# online