Design patterns: Interpreter
The Interpreter Pattern is a behavioral design pattern used to define the grammar of a simple language and interpret its expressions. It is used when you want to process a domain-specific language (DSL) or perform complex operations through predefined expressions and syntax rules. This pattern breaks complex expressions down into simpler sub-expressions and evaluates them recursively.
Strengths
- Easy to Add New Rules: It lets you add new interpretation rules easily, keeping the code organized and simple to extend.
- Modeling Custom Languages: Ideal for building interpreters for custom or domain-specific languages (DSLs), providing a clear structure for defining syntax rules.
- Decomposition and Recursion: It splits complex expressions into simpler sub-expressions that can be evaluated recursively, making it easier to interpret complex languages.
- Flexibility: Expressions can be represented flexibly as a tree structure, making it possible to handle compound or nested expressions.
- Maintainability: The pattern cleanly separates grammar and syntax rules, making the code more maintainable and easier to understand.
Use Case
Suppose we want to interpret a simple mathematical expression (for example, addition and subtraction) and evaluate its result.
PHP Code
// Interface for all expressions
interface Expression {
public function interpret(array $context);
}
// Expression for numbers
class Number implements Expression {
private $number;
public function __construct($number) {
$this->number = $number;
}
public function interpret(array $context) {
return $this->number;
}
}
// Expression for addition
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);
}
}
// Expression for subtraction
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);
}
}
// Usage
$expression = new Add(
new Number(5),
new Subtract(new Number(10), new Number(3))
);
$result = $expression->interpret([]);
echo "Result: $result\n"; // Output: Result: 12
Explanation
- Expression is the common interface for all expressions (numbers, addition, subtraction).
- Number represents a simple number (a terminal expression).
- Add and Subtract are nonterminal expressions that implement addition and subtraction respectively.
- interpret() is used to evaluate the expression, recursively calling the interpret methods on the child expressions.
In this example, the compound expression 5 + (10 - 3) is built and evaluated using the Interpreter pattern.
Conclusion
The Interpreter Pattern is useful when you need to implement interpreters for domain-specific languages or evaluate complex expressions. This pattern lets you represent and evaluate grammar rules in a structured and flexible way.