Что такое паттерн "Интерпретатор" (Interpreter)

Интерпретатор — поведенческий паттерн проектирования, который определяет грамматику и интерпретатор для простого языка. Он позволяет интерпретировать выражения заданного языка и выполнять их, представляя грамматические правила в виде классов.

Представьте, что вам нужно парсить и выполнять простые выражения или команды, написанные на своём DSL (Domain-Specific Language). Паттерн «Интерпретатор» помогает создать структуру, которая разбирает выражения и вычисляет результат.

Преимущества паттерна «Интерпретатор»

  • Позволяет создавать собственные языки и интерпретировать выражения.
  • Отделяет грамматику языка от кода, который выполняет операции.
  • Упрощает добавление новых правил языка.
  • Структурирует код парсера и интерпретатора.

Пример:

  • Язык арифметических выражений.
  • Правила: сложение, вычитание, числа.
  • Интерпретатор разбирает и вычисляет результат.

Где применяется паттерн «Интерпретатор»?

  • Языки программирования и скриптовые движки.
  • Парсеры запросов и выражений.
  • Конфигурационные файлы со сложной грамматикой.
  • Вычислительные и математические системы.

Пример реализации на JavaScript

// Абстрактный класс выражения class Expression { interpret(context) { throw new Error("Метод interpret() должен быть реализован"); } } // Числовое выражение class NumberExpression extends Expression { constructor(number) { super(); this.number = number; } interpret() { return this.number; } } // Сложение class AddExpression extends Expression { constructor(left, right) { super(); this.left = left; this.right = right; } interpret() { return this.left.interpret() + this.right.interpret(); } } // Вычитание class SubtractExpression extends Expression { constructor(left, right) { super(); this.left = left; this.right = right; } interpret() { return this.left.interpret() - this.right.interpret(); } } // Использование // Выражение: (5 + 3) - 2 const expression = new SubtractExpression( new AddExpression(new NumberExpression(5), new NumberExpression(3)), new NumberExpression(2), ); console.log(expression.interpret()); // 6

Когда стоит использовать паттерн «Интерпретатор»?

  • Требуется реализовать простой язык или выражения.
  • Нужно парсить и вычислять выражения.
  • Важно отделить грамматику языка от реализации.
  • Необходима расширяемость правил языка.

Отличие от других паттернов

  • В отличие от парсера, Интерпретатор тесно связан с грамматикой языка.
  • Отличается от стратегии тем, что работает с грамматическими структурами.

Плюсы паттерна

  • Чёткое разделение грамматики и выполнения.
  • Легко расширять язык добавлением новых правил.
  • Упрощает поддержку и развитие DSL.

Минусы паттерна

  • Может привести к большому количеству классов при сложной грамматике.
  • Неэффективен для сложных языков, требует компиляторов или парсеров.