# Design patterns: Chain of Responsibility

> Chain of Responsibility pattern con esempi in PHP

- URL: https://mautoblog.com/posts/design-patterns/chain-of-responsibility/
- Lingua: it
- Pubblicato: 2024-09-27
- Aggiornato: 2026-10-14
- Autore: Mauto
- Categorie: Sviluppo Software, Tecnologia
- Tags: Architettura Software, Best Practices, PHP
- Guida: Design Patterns (parte 14)
- Traduzione (en): https://mautoblog.com/en/posts/design-patterns/chain-of-responsibility/

---

Il **Chain of Responsibility Pattern** è un design pattern comportamentale che permette a più oggetti di gestire una richiesta senza che il mittente sappia quale oggetto specifico la elaborerà. Gli oggetti sono collegati in una catena e ogni oggetto gestisce la richiesta o la passa al successivo nella catena. Questo pattern separa l'emissione di una richiesta dalla sua gestione, aumentando la flessibilità nel collegare componenti e consentendo la modifica delle catene senza cambiare il codice client.

## Punti di Forza
1. **Eliminazione di Condizioni Complesse:**  Evita l'uso di strutture condizionali annidate e complesse (`if-else` o `switch`), migliorando la leggibilità e la manutenibilità del codice.
2. **Flessibilità nel Definire la Sequenza di Gestione:** Gli handler possono essere combinati in modo flessibile e dinamico, cambiando facilmente la sequenza in cui vengono processate le richieste senza modificare la logica del client.
3. **Separazione tra Mittente e Ricevitore:** Il mittente della richiesta non conosce l'handler finale, e la gestione può essere delegata lungo la catena, favorendo l'adesione al **principio di responsabilità singola**.
4. **Modificabilità Incrementale:** È facile aggiungere o rimuovere handler senza modificare il codice esistente, rendendo il sistema facilmente estendibile e manutenibile.
5. **Riuso dei Componenti:**  Gli handler possono essere riutilizzati in altre catene o contesti, favorendo il riuso del codice e riducendo la duplicazione.

## Caso d'Uso 
Supponiamo di voler implementare una catena di gestione per il processo di richiesta di supporto tecnico, dove diverse categorie di supporto (ad esempio, **livello base**, **livello avanzato** e **amministratore**) gestiscono le richieste in base alla loro complessità.

### Codice PHP

```php
// Interfaccia Handler
interface SupportHandler {
    public function setNext(SupportHandler $handler): SupportHandler;
    public function handle(string $issue): void;
}

// Handler Concreto per il Supporto Base
class BasicSupportHandler implements SupportHandler {
    private $nextHandler;

    public function setNext(SupportHandler $handler): SupportHandler {
        $this->nextHandler = $handler;
        return $handler;
    }

    public function handle(string $issue): void {
        if ($issue === "basic") {
            echo "Il supporto base gestisce il problema.\n";
        } elseif ($this->nextHandler) {
            $this->nextHandler->handle($issue);
        }
    }
}

// Handler Concreto per il Supporto Avanzato
class AdvancedSupportHandler implements SupportHandler {
    private $nextHandler;

    public function setNext(SupportHandler $handler): SupportHandler {
        $this->nextHandler = $handler;
        return $handler;
    }

    public function handle(string $issue): void {
        if ($issue === "advanced") {
            echo "Il supporto avanzato gestisce il problema.\n";
        } elseif ($this->nextHandler) {
            $this->nextHandler->handle($issue);
        }
    }
}

// Handler Concreto per il Supporto Amministrativo
class AdminSupportHandler implements SupportHandler {
    private $nextHandler;

    public function setNext(SupportHandler $handler): SupportHandler {
        $this->nextHandler = $handler;
        return $handler;
    }

    public function handle(string $issue): void {
        if ($issue === "admin") {
            echo "L'amministratore gestisce il problema.\n";
        } elseif ($this->nextHandler) {
            $this->nextHandler->handle($issue);
        }
    }
}

// Utilizzo
$basicHandler = new BasicSupportHandler();
$advancedHandler = new AdvancedSupportHandler();
$adminHandler = new AdminSupportHandler();

// Costruzione della catena di responsabilità
$basicHandler->setNext($advancedHandler)->setNext($adminHandler);

// Emettiamo una richiesta
echo "Problema: basic\n";
$basicHandler->handle("basic");

echo "\nProblema: advanced\n";
$basicHandler->handle("advanced");

echo "\nProblema: admin\n";
$basicHandler->handle("admin");

echo "\nProblema: unknown\n";
$basicHandler->handle("unknown");
```

## Spiegazione
- **BasicSupportHandler**, **AdvancedSupportHandler**, e **AdminSupportHandler** sono i diversi handler che gestiscono vari livelli di problemi di supporto.
- Ogni handler, nel metodo **handle()**, decide se può gestire la richiesta o la passa al successivo nella catena (impostato tramite **setNext()**).
- Se una richiesta non viene gestita da nessun handler, viene semplicemente ignorata o si può aggiungere un fallback.

## Conclusione
Il **Chain of Responsibility Pattern** è ideale per scenari in cui le richieste devono essere elaborate in modo flessibile da una serie di handler potenzialmente indipendenti.
Rende il sistema più estensibile e più facile da mantenere, riducendo la complessità del codice e migliorando la leggibilità.

[TORNA ALLA GUIDA](/posts/design-patterns/)

