# Design patterns: Strategy

> Strategy pattern con esempi in PHP

- URL: https://mautoblog.com/posts/design-patterns/strategy/
- 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 22)
- Traduzione (en): https://mautoblog.com/en/posts/design-patterns/strategy/

---
Lo **Strategy Pattern** è un pattern comportamentale che consente di definire una famiglia di algoritmi, incapsularli in classi separate e renderli intercambiabili tra loro. L'algoritmo da utilizzare può essere selezionato dinamicamente a runtime, rendendo il codice più flessibile e facilmente estendibile. Questo pattern è particolarmente utile quando si desidera evitare lunghi blocchi condizionali (come `if-else` o `switch-case`) per scegliere tra diversi algoritmi.

## Punti di Forza
1. **Separazione del codice**: Ogni algoritmo è incapsulato nella propria classe, separando la logica dell'algoritmo dal contesto in cui viene usato.
2. **Intercambiabilità degli algoritmi**: Gli algoritmi possono essere cambiati a runtime senza modificare il codice del client.
3. **Aumento della manutenibilità**: Aggiungere o modificare algoritmi non impatta il resto del codice.
4. **Estensibilità**: È facile aggiungere nuovi algoritmi implementando semplicemente una nuova classe che segue la stessa interfaccia.
5. **Favorisce la coesione**: Il contesto gestisce solo la logica di alto livello, mentre le strategie si occupano dell'implementazione specifica degli algoritmi.

### Caso d'uso: Sistema di pagamento

Immagina un sistema di pagamento che supporta diversi metodi: **Carta di Credito**, **PayPal** e **Bonifico Bancario**.
A seconda del metodo di pagamento scelto dall'utente, l'algoritmo per processare il pagamento cambia.

### Codice PHP
```php
<?php
// Interfaccia Strategia di pagamento
interface PaymentStrategy {
    public function pay($amount);
}

// Strategia pagamento con Carta di Credito
class CreditCardPayment implements PaymentStrategy {
    private $cardNumber;

    public function __construct($cardNumber) {
        $this->cardNumber = $cardNumber;
    }

    public function pay($amount) {
        // Mostriamo solo le ultime 4 cifre della carta
        $maskedNumber = '**** ' . substr($this->cardNumber, -4);
        echo "Pagamento di $amount effettuato con Carta di Credito numero: {$maskedNumber}.\n";
    }
}

// Strategia pagamento con PayPal
class PayPalPayment implements PaymentStrategy {
    private $email;

    public function __construct($email) {
        $this->email = $email;
    }

    public function pay($amount) {
        echo "Pagamento di $amount effettuato con PayPal all'indirizzo: {$this->email}.\n";
    }
}

// Strategia pagamento con Bonifico Bancario
class BankTransferPayment implements PaymentStrategy {
    private $bankAccount;

    public function __construct($bankAccount) {
        $this->bankAccount = $bankAccount;
    }

    public function pay($amount) {
        echo "Pagamento di $amount effettuato tramite Bonifico Bancario sul conto: {$this->bankAccount}.\n";
    }
}

// Classe Contesto per il pagamento
class PaymentContext {
    private $paymentStrategy;

    public function __construct(PaymentStrategy $paymentStrategy) {
        $this->paymentStrategy = $paymentStrategy;
    }

    public function setPaymentStrategy(PaymentStrategy $paymentStrategy) {
        $this->paymentStrategy = $paymentStrategy;
    }

    public function pay($amount) {
        $this->paymentStrategy->pay($amount);
    }
}

// Esempio d'uso
$context = new PaymentContext(new CreditCardPayment("1234-5678-9876-5432"));
$context->pay(100);  // Pagamento con Carta di Credito

$context->setPaymentStrategy(new PayPalPayment("user@example.com"));
$context->pay(200);  // Pagamento con PayPal

$context->setPaymentStrategy(new BankTransferPayment("IT60X0542811101000000123456"));
$context->pay(300);  // Pagamento con Bonifico Bancario
```

## Spiegazione
- **Interfaccia PaymentStrategy**: Definisce il metodo pay(), che ogni strategia di pagamento deve implementare.
- Strategie Concrete (**CreditCardPayment**, **PayPalPayment**, **BankTransferPayment**): Implementano l'interfaccia e gestiscono l'algoritmo di pagamento per il rispettivo metodo.
- **Classe PaymentContext**: Gestisce l'algoritmo di pagamento corrente e permette di cambiare strategia a runtime.
- Uso del contesto: L'utente può cambiare il metodo di pagamento senza modificare il contesto stesso; la strategia viene semplicemente sostituita.

## Conclusione
Lo Strategy Pattern separa chiaramente gli algoritmi dal contesto in cui sono utilizzati, migliorando la modularità e permettendo l'intercambiabilità degli algoritmi a runtime.
Questo è particolarmente utile in sistemi complessi che richiedono una varietà di algoritmi o logiche.

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