Interpreter — это поведенческий паттерн, который определяет грамматику простого языка и интерпретатор для его предложений.
Простыми словами: вы описываете правила «мини-языка» в виде классов, и каждый класс умеет вычислить свою часть выражения. Как калькулятор, который разбирает «3 + 5 * 2».
▪️ Пример:
Движок фильтрации пользователей по правилам: «возраст > 18 AND город = Москва». Каждое условие — узел дерева выражений.
// Абстрактное выражение
interface Expression {
boolean interpret(Map<String, String> context);
}
// Терминальное выражение — проверка одного поля
class Equals implements Expression {
private final String key;
private final String value;
public Equals(String key, String value) {
this.key = key;
this.value = value;
}
public boolean interpret(Map<String, String> context) {
return value.equals(context.get(key));
}
}
class GreaterThan implements Expression {
private final String key;
private final int threshold;
public GreaterThan(String key, int threshold) {
this.key = key;
this.threshold = threshold;
}
public boolean interpret(Map<String, String> context) {
return Integer.parseInt(context.getOrDefault(key, "0")) > threshold;
}
}
// Нетерминальные выражения — комбинаторы
class And implements Expression {
private final Expression left, right;
public And(Expression left, Expression right) {
this.left = left;
this.right = right;
}
public boolean interpret(Map<String, String> context) {
return left.interpret(context) && right.interpret(context);
}
}
class Or implements Expression {
private final Expression left, right;
public Or(Expression left, Expression right) {
this.left = left;
this.right = right;
}
public boolean interpret(Map<String, String> context) {
return left.interpret(context) || right.interpret(context);
}
}
// Использование: возраст > 18 AND город = Москва
Expression rule = new And(
new GreaterThan("age", 18),
new Equals("city", "Москва")
);
Map<String, String> user1 = Map.of("age", "25", "city", "Москва");
Map<String, String> user2 = Map.of("age", "16", "city", "Москва");
System.out.println(rule.interpret(user1)); // true
System.out.println(rule.interpret(user2)); // false
▪️ Когда использовать
— Есть простой язык или набор правил, которые нужно интерпретировать
— Грамматика стабильна, но выражений — много
— Пример: SpEL (Spring Expression Language), регулярные выражения
▪️ Минус
Для сложных грамматик дерево классов разрастается и становится неуправляемым — лучше использовать парсер-генераторы (ANTLR).
🐸 Библиотека собеса по Java
#patterns