Python: il Decorator Pattern

Python: il Decorator Pattern

Il Design Pattern del Decorator è uno dei concetti fondamentali della programmazione orientata agli oggetti e offre un modo flessibile per estendere le funzionalità di una classe senza modificarne il codice sorgente. In Python, il Decorator Pattern è implementato sfruttando la natura dinamica del linguaggio e la capacità di trattare le funzioni come cittadini di prima classe.

Concetti di base

Il Decorator Pattern consente di aggiungere nuove funzionalità a un oggetto esistente senza modificarne la sua struttura. Questo è particolarmente utile quando si desidera estendere il comportamento di una classe senza dover creare una classe sottoclasse per ogni combinazione possibile di funzionalità aggiuntive.

In Python, i decorator sono funzioni che accettano un'altra funzione e ne estendono o modificano il comportamento. I decorator possono essere applicati a una funzione o a un metodo di classe utilizzando la sintassi @decorator.

Implementazione pratica

Consideriamo un esempio semplice di un Decorator Pattern applicato a una classe Coffee che rappresenta una bevanda. Iniziamo definendo la classe base:


class Coffee:
    def cost(self):
        return 5

Ora vogliamo aggiungere decoratori per modificare il costo del caffè in base ad alcuni attributi, come la dimensione della tazza o l'aggiunta di latte. Creiamo quindi alcuni decoratori:


def with_milk(cost_fn):
    def wrapper(self):
        return cost_fn(self) + 2
    return wrapper

def large_size(cost_fn):
    def wrapper(self):
        return cost_fn(self) + 3
    return wrapper

Ora, possiamo applicare questi decoratori alla nostra classe Coffee utilizzando la sintassi @:


@with_milk
class MilkCoffee(Coffee):
    pass

@large_size
class LargeCoffee(Coffee):
    pass

@large_size
@with_milk
class LargeMilkCoffee(Coffee):
    pass

Ora possiamo creare istanze di queste classi decorate e ottenere il costo totale del caffè con le varie modifiche:


regular_coffee = Coffee()
print("Costo del caffè normale:", regular_coffee.cost())

milk_coffee = MilkCoffee()
print("Costo del caffè con latte:", milk_coffee.cost())

large_coffee = LargeCoffee()
print("Costo del caffè grande:", large_coffee.cost())

large_milk_coffee = LargeMilkCoffee()
print("Costo del caffè grande con latte:", large_milk_coffee.cost())

Vantaggi del Decorator Pattern

  1. Flessibilità: Il Decorator Pattern consente di comporre liberamente le funzionalità, aggiungendo o rimuovendo decoratori secondo necessità.

  2. Leggibilità del codice: Il codice rimane pulito e leggibile poiché le funzionalità aggiuntive sono separate in decorator.

  3. Riutilizzo del codice: I decoratori possono essere riutilizzati in diverse parti del codice, migliorando l'efficienza dello sviluppo.

Conclusioni

In conclusione, il Decorator Pattern in Python è una tecnica potente per estendere il comportamento delle classi in modo flessibile e mantenibile. Sfruttando la sintassi chiara e concisa di Python, è possibile migliorare la modularità e la leggibilità del codice.

Torna su