Interpreter#
The Interpreter pattern is a behavioral design pattern that defines a grammatical representation for a language and provides an interpreter to deal with this grammar. This pattern is used to interpret sentences in a language.
In simpler terms, the Interpreter pattern is like having a translator for a specific set of instructions or commands. It helps in understanding and executing those commands.
UML Diagram#
+-------------------+ +-------------------+
| AbstractExpression|<-------| TerminalExpression|
|-------------------| |-------------------|
| +interpret() | | +interpret() |
+-------------------+ +-------------------+
^
|
+----------------------+
| NonTerminalExpression|
|----------------------|
| +interpret() |
+----------------------+
In this diagram, AbstractExpression is an interface with the method interpret(). TerminalExpression and NonTerminalExpression are classes that implement the AbstractExpression interface. The arrows indicate that the TerminalExpression and NonTerminalExpression classes inherit from the AbstractExpression interface.
Java Example#
import java.util.Map;
interface Expression {
int interpret(Map<String, Integer> context);
}
class Number implements Expression {
private final int number;
public Number(int number) {
this.number = number;
}
@Override
public int interpret(Map<String, Integer> context) {
return number;
}
}
class Plus implements Expression {
private final Expression leftOperand;
private final Expression rightOperand;
public Plus(Expression leftOperand, Expression rightOperand) {
this.leftOperand = leftOperand;
this.rightOperand = rightOperand;
}
@Override
public int interpret(Map<String, Integer> context) {
return leftOperand.interpret(context) + rightOperand.interpret(context);
}
}
class Minus implements Expression {
private final Expression leftOperand;
private final Expression rightOperand;
public Minus(Expression leftOperand, Expression rightOperand) {
this.leftOperand = leftOperand;
this.rightOperand = rightOperand;
}
@Override
public int interpret(Map<String, Integer> context) {
return leftOperand.interpret(context) - rightOperand.interpret(context);
}
}
public class InterpreterExample {
public static void main(String[] args) {
Expression expr = new Plus(new Number(5), new Minus(new Number(10), new Number(3)));
int result = expr.interpret(Map.of());
System.out.println("Result: " + result); // Output: Result: 12
}
}
Python Example#
from __future__ import annotations
from abc import ABC, abstractmethod
from typing import Dict
class Expression(ABC):
@abstractmethod
def interpret(self, context: Dict[str, int]) -> int:
pass
class Number(Expression):
def __init__(self, number: int) -> None:
self._number = number
def interpret(self, context: Dict[str, int]) -> int:
return self._number
class Plus(Expression):
def __init__(self, left_operand: Expression, right_operand: Expression) -> None:
self._left_operand = left_operand
self._right_operand = right_operand
def interpret(self, context: Dict[str, int]) -> int:
return self._left_operand.interpret(context) + self._right_operand.interpret(context)
class Minus(Expression):
def __init__(self, left_operand: Expression, right_operand: Expression) -> None:
self._left_operand = left_operand
self._right_operand = right_operand
def interpret(self, context: Dict[str, int]) -> int:
return self._left_operand.interpret(context) - self._right_operand.interpret(context)
if __name__ == "__main__":
expr = Plus(Number(5), Minus(Number(10), Number(3)))
result = expr.interpret({})
print(f"Result: {result}") # Output: Result: 12