Menu
Coddy logo textTech

Pattern Decorator

Fa parte della sezione Programmazione orientata agli oggetti del percorso Dart di Coddy. Lezione 96 di 110.

Il pattern Decorator ti permette di aggiungere dinamicamente nuovi comportamenti agli oggetti avvolgendoli in oggetti speciali chiamati decoratori. A differenza dell'ereditarietà, che aggiunge comportamenti in fase di compilazione, i decoratori assegnano responsabilità aggiuntive in fase di esecuzione senza modificare la classe originale.

L'idea chiave è che sia l'oggetto originale sia i decoratori implementano la stessa interfaccia.

Un decoratore avvolge l’oggetto originale, delega a esso e aggiunge il proprio comportamento prima o dopo:

abstract class Coffee {
  String getDescription();
  double getCost();
}

class SimpleCoffee implements Coffee {
  @override
  String getDescription() => 'Simple Coffee';

  @override
  double getCost() => 2.0;
}

class MilkDecorator implements Coffee {
  final Coffee _coffee;
  MilkDecorator(this._coffee);

  @override
  String getDescription() => '${_coffee.getDescription()}, Milk';

  @override
  double getCost() => _coffee.getCost() + 0.5;
}

class SugarDecorator implements Coffee {
  final Coffee _coffee;
  SugarDecorator(this._coffee);

  @override
  String getDescription() => '${_coffee.getDescription()}, Sugar';

  @override
  double getCost() => _coffee.getCost() + 0.2;
}

void main() {
  Coffee coffee = SimpleCoffee();
  coffee = MilkDecorator(coffee);
  coffee = SugarDecorator(coffee);

  print(coffee.getDescription());  // Caffè semplice, latte, zucchero
  print(coffee.getCost());         // 2.7
}

Ogni decoratore avvolge l'oggetto precedente e lo arricchisce. Puoi concatenare più decoratori in qualsiasi combinazione, creando un comportamento flessibile senza creare una sottoclasse per ogni possibile combinazione. Questo pattern è ideale quando devi aggiungere funzionalità agli oggetti senza influire su altri oggetti della stessa classe.

challenge icon

Sfida

Facile

Costruiamo un sistema per ordinare pizze usando il pattern Decorator! Creerai una pizza di base che può essere arricchita con vari condimenti, in cui ogni condimento avvolge l’elemento precedente e contribuisce sia alla descrizione sia al prezzo.

Organizzerai il codice in due file:

  • pizza.dart: questo file contiene l’interfaccia della pizza e tutte le classi decorator. Inizia con una classe astratta Pizza che definisce due metodi: String getDescription() e double getPrice(). Poi crea una classe PlainPizza che implementa Pizza: restituisce Plain Pizza come descrizione e costa 8.0. Ora crea tre classi decorator, ognuna delle quali avvolge una Pizza e la arricchisce:
    • CheeseDecorator - aggiunge , Cheese alla descrizione e 1.5 al prezzo
    • PepperoniDecorator - aggiunge , Pepperoni alla descrizione e 2.0 al prezzo
    • MushroomDecorator - aggiunge , Mushrooms alla descrizione e 1.25 al prezzo
    Ogni decorator deve implementare Pizza, accettare una Pizza nel proprio costruttore e delegare alla pizza avvolta prima di aggiungere il proprio contributo.
  • main.dart: importa il file della pizza e mostra come i decorator si combinano per creare un ordine personalizzato. Inizia con una PlainPizza, poi avvolgila con CheeseDecorator, quindi avvolgi il risultato con PepperoniDecorator e infine avvolgi tutto con MushroomDecorator. Stampa la descrizione della pizza finale, poi stampa Total: $ seguito dal prezzo.

Nota come ogni decorator si basa sul precedente: stai creando una pizza ricca di condimenti combinando decorator semplici, ciascuno con una singola responsabilità!

Output previsto:

Plain Pizza, Cheese, Pepperoni, Mushrooms
Total: $12.75

Provalo tu

import 'pizza.dart';

void main() {
  // TODO: Crea una PlainPizza
  
  // TODO: Avvolgila con CheeseDecorator
  
  // TODO: Avvolgi il risultato con PepperoniDecorator
  
  // TODO: Avvolgi il tutto con MushroomDecorator
  
  // TODO: Stampa la descrizione della pizza finale
  
  // TODO: Stampa "Total: $" seguito dal prezzo
}
quiz iconMettiti alla prova

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

Esercitati da solo: Compilatore Dart online