Interpreter (Интерпретатор)
Шаблон проектирования "Интерпретатор" (Interpreter) используется для определения грамматики и интерпретации языка. Этот паттерн позволяет создавать интерпретаторы для языков, используя классы, которые представляют грамматические правила. Он особенно полезен, когда необходимо интерпретировать выражения или команды, которые могут быть представлены в виде дерева.
Основные компоненты паттерна "Интерпретатор":
- Контекст (Context): класс, который содержит информацию, необходимую для интерпретации выражений.
- Абстрактный выражение (Abstract Expression): интерфейс или абстрактный класс, который определяет метод для интерпретации.
- Конкретные выражения (Concrete Expressions): классы, реализующие абстрактное выражение и определяющие конкретные правила интерпретации.
- Клиент (Client): класс, который создает и использует интерпретатор.
Пример на Java
Рассмотрим пример, в котором мы создаем простой интерпретатор для арифметических выражений, состоящих из чисел и операций сложения и вычитания.
import java.util.HashMap;
import java.util.Map;
// Интерфейс выражения
interface Expression {
int interpret(Map<String, Integer> context);
}
// Конкретное выражение: Число
class NumberExpression implements Expression {
private int number;
public NumberExpression(int number) {
this.number = number;
}
@Override
public int interpret(Map<String, Integer> context) {
return number;
}
}
// Конкретное выражение: Переменная
class VariableExpression implements Expression {
private String variable;
public VariableExpression(String variable) {
this.variable = variable;
}
@Override
public int interpret(Map<String, Integer> context) {
return context.get(variable);
}
}
// Конкретное выражение: Сложение
class AddExpression implements Expression {
private Expression left;
private Expression right;
public AddExpression(Expression left, Expression right) {
this.left = left;
this.right = right;
}
@Override
public int interpret(Map<String, Integer> context) {
return left.interpret(context) + right.interpret(context);
}
}
// Конкретное выражение: Вычитание
class SubtractExpression implements Expression {
private Expression left;
private Expression right;
public SubtractExpression(Expression left, Expression right) {
this.left = left;
this.right = right;
}
@Override
public int interpret(Map<String, Integer> context) {
return left.interpret(context) - right.interpret(context);
}
}
// Пример использования
public class InterpreterPatternExample {
public static void main(String[] args) {
// Создаем контекст с переменными
Map<String, Integer> context = new HashMap<>();
context.put("x", 10);
context.put("y", 5);
// Создаем выражение: x + y - 2
Expression expression = new SubtractExpression(
new AddExpression(new VariableExpression("x"), new VariableExpression("y")),
new NumberExpression(2)
);
// Интерпретируем выражение
int result = expression.interpret(context);
System.out.println("Результат: " + result); // Результат: 13
}
}
Объяснение кода:
- Интерфейс
Expression
определяет методinterpret
, который принимает контекст и возвращает результат интерпретации. - Класс
NumberExpression
представляет числовое значение и возвращает его при интерпретации. - Класс
VariableExpression
представляет переменную и возвращает ее значение из контекста. - Классы
AddExpression
иSubtractExpression
представляют операции сложения и вычитания соответственно. Они принимают два выражения и интерпретируют их, выполняя соответствующую операцию. - В методе
main
мы создаем контекст с переменными и выражениеx + y - 2
, а затем интерпретируем его, получая результат.
Таким образом, паттерн "Интерпретатор" позволяет создавать интерпретаторы для языков или выражений, определяя грамматику и правила интерпретации с помощью классов. Это делает код более структурированным и легким для расширения, если необходимо добавить новые операции или правила.