Pattern Template Method
Fa parte della sezione Programmazione orientata agli oggetti del percorso Java di Coddy. Lezione 73 di 87.
Il Template Method Pattern è un pattern di progettazione comportamentale che definisce lo scheletro di un algoritmo in una classe base, consentendo alle sottoclassi di sovrascrivere passaggi specifici senza modificare la struttura complessiva. Pensalo come una ricetta: il processo generale di preparazione rimane lo stesso, ma i singoli ingredienti o le tecniche possono variare.
Il modello utilizza una classe astratta con un metodo template che richiama una sequenza di passaggi. Alcuni passaggi hanno implementazioni predefinite, mentre altri sono astratti e devono essere implementati dalle sottoclassi:
abstract class DataProcessor {
// Metodo template - definisce la struttura dell'algoritmo
public final void process() {
readData();
processData();
saveData();
}
abstract void readData();
abstract void processData();
// Implementazione predefinita (metodo hook)
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");
}
}Il metodo template è in genere contrassegnato come final per impedire alle sottoclassi di modificare la struttura dell’algoritmo. Quando viene chiamato, esegue la stessa sequenza per tutte le sottoclassi:
DataProcessor csv = new CSVProcessor();
csv.process();
// Output:
// Lettura del file CSV
// Analisi dei dati CSV
// Salvataggio nella posizione predefinitaIl Pattern Template Method è ideale quando hai algoritmi che condividono la stessa struttura ma differiscono in passaggi specifici. Promuove il riutilizzo del codice collocando la logica comune nella classe base e consentendo la personalizzazione tramite ereditarietà.
Sfida
FacileCostruiamo un sistema di generazione di documenti usando il Template Method Pattern! Creerai un framework in cui diversi tipi di documenti (rapporti e fatture) seguono lo stesso processo di generazione, ma personalizzano passaggi specifici. È perfetto per gli scenari in cui il flusso di lavoro complessivo è fisso, ma i dettagli variano in base al tipo di documento.
Organizzerai il codice in quattro file:
DocumentGenerator.java: crea la classe base astratta che definisce il template method. Il tuoDocumentGeneratordovrebbe avere:Un metodo
finalchiamatogenerateDocument()che definisce lo scheletro dell'algoritmo chiamando tre passaggi nell'ordine seguente:createHeader(),createBody()ecreateFooter().Due metodi astratti:
createHeader()ecreateBody(), che le sottoclassi devono implementare.Un metodo hook
createFooter()con un'implementazione predefinita che stampa--- End of Document ---.ReportGenerator.java: crea una sottoclasse concreta per generare rapporti. Dovrà ricevere un titolo del rapporto (String) tramite il costruttore.Il metodo
createHeader()stampa=== REPORT: [title] ===Il metodo
createBody()stampaReport content goes here...Usa il piè di pagina predefinito ereditato.
InvoiceGenerator.java: crea un'altra sottoclasse concreta per generare fatture. Dovrà ricevere un nome del cliente (String) e un importo (double) tramite il costruttore.Il metodo
createHeader()stampa*** INVOICE ***Il metodo
createBody()stampaCustomer: [name]su una riga, poiAmount Due: $[amount]sulla riga successiva (formatta l'importo con due cifre decimali).Sovrascrivi
createFooter()per stampareThank you for your business!Main.java: metti insieme il tuo sistema basato sul template method! Riceverai tre input: un titolo del rapporto (String), un nome del cliente (String) e un importo della fattura (double).Crea un
ReportGeneratorcon il titolo e chiamagenerateDocument(). Stampa una riga vuota come separazione. Poi crea unInvoiceGeneratorcon il nome del cliente e l'importo, e chiamagenerateDocument().
Riceverai tre input nell'ordine seguente: titolo del rapporto (String), nome del cliente (String) e importo della fattura (double).
Per esempio, con gli input Q4 Sales, Acme Corp e 1500.00, il tuo output sarà:
=== REPORT: Q4 Sales ===
Report content goes here...
--- End of Document ---
*** INVOICE ***
Customer: Acme Corp
Amount Due: $1500.00
Thank you for your business!Nota come entrambi i tipi di documento seguano lo stesso processo in tre passaggi definito nel template method, ma personalizzino i passaggi in modo diverso. ReportGenerator usa il piè di pagina predefinito, mentre InvoiceGenerator ne fornisce uno personalizzato. Questa è la potenza dei metodi hook nel Template Method Pattern!
Provalo tu
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Leggi i dati in ingresso
String reportTitle = scanner.nextLine();
String customerName = scanner.nextLine();
double invoiceAmount = scanner.nextDouble();
// TODO: Crea un ReportGenerator con il titolo e chiama generateDocument()
// TODO: Stampa una riga vuota per separare
// TODO: Crea un InvoiceGenerator con il nome del cliente e l'importo, e chiama generateDocument()
}
}
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 a oggetti
File esterniIntroduzione alla programmazione a oggettiClassi e oggettiLa parola chiave thisMetodiCampi (attributi)Metodo costruttoreSovraccarico dei costruttoriRipasso - Calcolatrice semplice4Ereditarietà
Ereditarietà di base (extends)La parola chiave superSovrascrittura dei metodi (@Override)Concatenamento dei costruttoriLa classe ObjectEreditarietà singola e multilivelloPerché non esiste l'ereditarietà multipla delle classiRiepilogo: gerarchia dei dipendenti7Metodi speciali e classe Object
Metodo toString()equals() e hashCode()Metodo clone()compareTo() e ComparableInterfaccia ComparatorRiepilogo - Ordinamento personalizzato2Modificatori di accesso e incapsulamento
Panoramica dei livelli di accessoMetodi getter e setterNascondimento delle informazioniLa parola chiave finalRiepilogo - Gestore di conti bancari5Polimorfismo
Nozioni di base sull'overloading dei metodiOverride dei metodi (a runtime)Upcasting e downcastingL'operatore instanceofClassi e metodi astrattiRiepilogo - Calcolatore di forme8Concetti avanzati di OOP
Composizione vs ereditarietàAggregazione vs composizioneClassi interne, annidate e anonimeEnum e metodi degli EnumRecord (Java 16+)Classi sealed (Java 17+)11Modelli di progettazione Parte 1
Introduzione ai modelli di progettazionePattern SingletonPattern FactoryPattern BuilderPattern ObserverPattern Strategy3Proprietà di classe e membri statici
Variabili di istanza e staticheMetodi staticiBlocchi staticiCostanti (static final)Riepilogo - Contatore e utility6Interfacce e classi astratte
Introduzione alle interfacceImplementazione delle interfacceImplementazione di più interfacceMetodi default e static nelle interfacceClassi astratte e interfacce a confrontoInterfacce funzionaliRiepilogo: sistema di pagamento9Tipi generici
Introduzione ai tipi genericiClassi genericheMetodi genericiParametri di tipo con limitiCaratteri jolly (?, extends, super)Riepilogo - Contenitore generico12Modelli di progettazione – Parte 2
Pattern CommandPattern AdapterPattern DecoratorPattern Template MethodPattern StatePattern CompositePattern IteratorEsercitati da solo: Compilatore Java online