Pattern Composite
Fa parte della sezione Programmazione orientata agli oggetti del percorso Java di Coddy. Lezione 75 di 87.
Il Composite Pattern è un pattern strutturale che consente di comporre oggetti in strutture ad albero per rappresentare gerarchie parte-tutto. Permette ai client di trattare in modo uniforme oggetti singoli e composizioni di oggetti tramite un'interfaccia comune.
Pensa a un file system: una cartella può contenere file e altre cartelle, che a loro volta possono contenere altri file e cartelle. Che tu abbia a che fare con un singolo file o con un’intera struttura di cartelle, vuoi eseguire operazioni come «ottenere le dimensioni» sempre allo stesso modo. Il pattern definisce un’interfaccia Component, oggetti Leaf (elementi singoli) e oggetti Composite (contenitori che ospitano elementi figli):
interface FileComponent {
void display(String indent);
int getSize();
}
class File implements FileComponent {
private String name;
private int size;
public File(String name, int size) {
this.name = name;
this.size = size;
}
public void display(String indent) {
System.out.println(indent + name + " (" + size + "KB)");
}
public int getSize() {
return size;
}
}
class Folder implements FileComponent {
private String name;
private List<FileComponent> children = new ArrayList<>();
public Folder(String name) {
this.name = name;
}
public void add(FileComponent component) {
children.add(component);
}
public void display(String indent) {
System.out.println(indent + name + "/");
for (FileComponent child : children) {
child.display(indent + " ");
}
}
public int getSize() {
return children.stream().mapToInt(FileComponent::getSize).sum();
}
}Il composito delega le operazioni ai suoi figli, consentendo strutture ricorsive. I client interagiscono con l'albero senza sapere se stanno lavorando con una foglia o con un composito:
Folder root = new Folder("Documents");
root.add(new File("resume.pdf", 150));
Folder photos = new Folder("Photos");
photos.add(new File("vacation.jpg", 2000));
root.add(photos);
root.display("");
System.out.println("Total: " + root.getSize() + "KB");Il pattern Composite è ideale per rappresentare gerarchie come organigrammi, componenti dell’interfaccia utente o sistemi di menu, in cui devi trattare gruppi e singoli elementi in modo identico.
Sfida
FacileCostruiamo un sistema di organigrammi usando il Composite Pattern! Creerai una struttura in cui i reparti possono contenere dipendenti e altri sottoreparti, permettendoti di calcolare gli stipendi totali e visualizzare la gerarchia in modo uniforme, sia che tu stia esaminando un singolo dipendente sia un'intera divisione.
Organizzerai il codice in quattro file:
OrganizationComponent.java: Definisci l'interfaccia del componente che sarà implementata sia dai dipendenti sia dai reparti. Dovrebbe dichiarare due metodi:showDetails(String indent)per visualizzare il componente con la corretta indentazione egetSalary(), che restituisce lo stipendio totale come numero intero.Employee.java: Crea la classe foglia che rappresenta i singoli lavoratori. UnEmployeeha un nome (String) e uno stipendio (int), entrambi impostati tramite il costruttore. Quando viene chiamatoshowDetails, dovrebbe stampare[indent][name]: $[salary]. Il metodogetSalaryrestituisce semplicemente lo stipendio del dipendente.Department.java: Crea la classe composita che può contenere sia dipendenti sia sottoreparti. UnDepartmentha un nome (String) e mantiene un elenco di elementi figliOrganizationComponent. Dovrebbe avere un metodoadd(OrganizationComponent component)per aggiungere membri. Quando viene chiamatoshowDetails, stampa[indent][name] Department, quindi chiamashowDetailssu ogni elemento figlio con un'indentazione maggiore (aggiungi due spazi). Il metodogetSalaryrestituisce la somma degli stipendi di tutti gli elementi figli.Main.java: Crea la tua organizzazione! Riceverai quattro input: i nomi e gli stipendi di due dipendenti e il nome di un sottoreparto con un dipendente.Crea un reparto "Engineering" come radice. Aggiungici due dipendenti usando le prime due coppie nome/stipendio. Poi crea un sottoreparto usando il terzo input, aggiungici un dipendente usando la quarta coppia nome/stipendio e aggiungi questo sottoreparto a Engineering.
Chiama
showDetails("")sul reparto Engineering, quindi stampa lo stipendio totale nel formatoTotal Salary: $[amount].
Riceverai gli input in questo ordine: nome di employee1 (String), stipendio di employee1 (int), nome di employee2 (String), stipendio di employee2 (int), nome del sottoreparto (String), nome di employee3 (String), stipendio di employee3 (int).
Ad esempio, con gli input Alice, 75000, Bob, 65000, QA, Charlie, 55000, il tuo output sarebbe:
Engineering Department
Alice: $75000
Bob: $65000
QA Department
Charlie: $55000
Total Salary: $195000Nota come gli stessi metodi showDetails e getSalary funzionano senza problemi sia quando vengono chiamati su un singolo dipendente sia su un intero reparto contenente sottoreparti annidati. La struttura composita gestisce automaticamente la ricorsione, permettendoti di trattare uniformemente l'intera gerarchia!
Provalo tu
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// Read inputs
String emp1Name = scanner.nextLine();
int emp1Salary = Integer.parseInt(scanner.nextLine());
String emp2Name = scanner.nextLine();
int emp2Salary = Integer.parseInt(scanner.nextLine());
String subDeptName = scanner.nextLine();
String emp3Name = scanner.nextLine();
int emp3Salary = Integer.parseInt(scanner.nextLine());
// TODO: Create the "Engineering" department as the root
// TODO: Create and add two employees to Engineering using emp1 and emp2 data
// TODO: Create a sub-department using subDeptName
// TODO: Create and add one employee to the sub-department using emp3 data
// TODO: Add the sub-department to Engineering
// TODO: Call showDetails("") on the Engineering department
// TODO: Print the total salary in format: Total Salary: $[amount]
}
}
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