Middle
Cos'è un decoratore (Decorator)?
sobes.tech AI
Risposta dell'AI
Il decoratore è un pattern di progettazione strutturale che consente di aggiungere dinamicamente nuove funzionalità a un oggetto, senza modificarne la struttura. Avvolge l'oggetto, fornendo la stessa interfaccia dell'oggetto avvolto, ma aggiungendo o modificando il suo comportamento.
Elementi principali:
- Componente (Component): Interfaccia o classe astratta che definisce la funzionalità comune per gli oggetti avvolti e i decoratori.
- Componente Concreto (Concrete Component): Implementazione del componente, oggetto di base a cui si aggiunge funzionalità.
- Decoratore (Decorator): Classe astratta che implementa l'interfaccia del componente e contiene un riferimento a un oggetto componente.
- Decoratore Concreto (Concrete Decorator): Implementazione del decoratore che aggiunge funzionalità specifica prima o dopo la chiamata del metodo dell'oggetto avvolto.
Esempio in Python:
# Componente
class Coffee:
def get_cost(self):
return 5 # Costo base del caffè
def get_description(self):
return "Caffè semplice"
# Componente Concreto
class SimpleCoffee(Coffee):
pass
# Decoratore
class CoffeeDecorator(Coffee):
def __init__(self, coffee):
self._coffee = coffee
def get_cost(self):
return self._coffee.get_cost()
def get_description(self):
return self._coffee.get_description()
# Decoratore Concreto
class MilkDecorator(CoffeeDecorator):
def get_cost(self):
return self._coffee.get_cost() + 2 # Aggiunge il costo del latte
def get_description(self):
return self._coffee.get_description() + ", Latte"
# Uso
# simple_coffee = SimpleCoffee()
# print(f"Costo: {simple_coffee.get_cost()}, Descrizione: {simple_coffee.get_description()}")
# coffee_with_milk = MilkDecorator(simple_coffee)
# print(f"Costo: {coffee_with_milk.get_cost()}, Descrizione: {coffee_with_milk.get_description()}")
Vantaggi:
- Flessibilità: La funzionalità può essere aggiunta durante l'esecuzione.
- Evitare sottoclassi: Permette di evitare la creazione di molte sottoclassi per ogni combinazione di comportamenti.
- Separazione delle responsabilità: Ogni aggiunta di comportamento viene gestita in una classe separata.
Svantaggi:
- Potrebbe aumentare il numero di classi.
- Il debug può diventare più complesso a causa della catena di avvolgimenti.