Design patterns: Interpreter

Mauto 3 min

L’Interpreter Pattern è un design pattern comportamentale che viene utilizzato per definire la grammatica di un linguaggio semplice e interpretare le sue espressioni. Viene impiegato quando si vuole elaborare un linguaggio di dominio specifico (DSL) o eseguire operazioni complesse tramite espressioni e regole di sintassi predefinite. Questo pattern suddivide le espressioni complesse in sotto-espressioni più semplici e le valuta ricorsivamente.

Punti di Forza

  1. Facilità nell’Aggiungere Nuove Regole: Consente di aggiungere nuove regole di interpretazione facilmente, mantenendo il codice organizzato e semplice da estendere.
  2. Modellazione di Linguaggi Personalizzati: Ideale per creare interpreti per linguaggi personalizzati o di dominio specifico (DSL), fornendo una struttura chiara per la definizione di regole sintattiche.
  3. Suddivisione e Ricorsione: Divide espressioni complesse in sotto-espressioni più semplici, che possono essere valutate ricorsivamente, facilitando l’interpretazione di linguaggi complessi.
  4. Flessibilità: Le espressioni possono essere rappresentate in modo flessibile come una struttura ad albero, consentendo di gestire espressioni composte o nidificate.
  5. Manutenibilità: Il pattern consente di separare in modo chiaro le regole grammaticali e sintattiche, rendendo il codice più manutenibile e comprensibile.

Caso d’Uso

Supponiamo di voler interpretare una semplice espressione matematica (ad esempio, somma e sottrazione) e valutarne il risultato.

Codice PHP

// Interfaccia per tutte le espressioni
interface Expression {
    public function interpret(array $context);
}

// Espressione per i numeri
class Number implements Expression {
    private $number;

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

    public function interpret(array $context) {
        return $this->number;
    }
}

// Espressione per la somma
class Add implements Expression {
    private $leftExpression;
    private $rightExpression;

    public function __construct(Expression $leftExpression, Expression $rightExpression) {
        $this->leftExpression = $leftExpression;
        $this->rightExpression = $rightExpression;
    }

    public function interpret(array $context) {
        return $this->leftExpression->interpret($context) + $this->rightExpression->interpret($context);
    }
}

// Espressione per la sottrazione
class Subtract implements Expression {
    private $leftExpression;
    private $rightExpression;

    public function __construct(Expression $leftExpression, Expression $rightExpression) {
        $this->leftExpression = $leftExpression;
        $this->rightExpression = $rightExpression;
    }

    public function interpret(array $context) {
        return $this->leftExpression->interpret($context) - $this->rightExpression->interpret($context);
    }
}

// Utilizzo
$expression = new Add(
    new Number(5),
    new Subtract(new Number(10), new Number(3))
);

$result = $expression->interpret([]);
echo "Risultato: $result\n";  // Output: Risultato: 12

Spiegazione

  • Expression è l’interfaccia comune per tutte le espressioni (numeri, somma, sottrazione).
  • Number rappresenta un numero semplice (espressione terminale).
  • Add e Subtract sono espressioni non terminali che implementano rispettivamente la somma e la sottrazione.
  • interpret() viene utilizzato per valutare l’espressione, ricorsivamente chiamando i metodi interpret sulle espressioni figlie.

In questo esempio, l’espressione composta 5 + (10 - 3) viene creata e valutata usando il pattern Interpreter.

Conclusione

L’Interpreter Pattern è utile quando si devono implementare interpreti per linguaggi di dominio specifico o per valutare espressioni complesse. Questo pattern permette di rappresentare e valutare regole grammaticali in modo strutturato e flessibile.

TORNA ALLA GUIDA

content_copy Copiato