Interpreter Pattern
Interpreter: start from the problem
See the responsibilities
A feature rule says that a visitor must be a member and in a supported region. Repeatedly scattering rule evaluation through application code can make the small rule language hard to inspect.
This is a behavioral pattern lesson. Follow the responsibilities, inspect the small JavaScript example and compare the design choices. The example is local teaching code; its boundary is explained before you apply the idea to a real service.
What you’ll learn
- Explain the problem Interpreter addresses and the roles involved.
- Follow the example and distinguish this pattern from nearby alternatives.
- Choose when the benefit justifies the extra responsibilities and testing.
How the responsibilities work
Interpreter models a defined grammar as expressions that evaluate under a context. Terminal expressions read simple values; compound expressions combine other expressions according to the grammar. The scope is a small language whose rules you can validate and explain.
The example constructs an expression tree directly for AND and named flags. It does not parse arbitrary text and never calls eval. A production language also needs parsing, type checks, limits and useful error messages.
Follow a small example
Read the JavaScript from top to bottom and compare the expected output. The values are chosen to make this pattern’s responsibility visible. This example runs in one local execution context; it does not create remote services, durable storage or production access controls.
JavaScript · local teaching example
const flag = name => ({evaluate: context => context[name] === true});
const and = (left, right) => ({evaluate: context => left.evaluate(context) && right.evaluate(context)});
const rule = and(flag('member'), flag('supportedRegion'));
console.log(rule.evaluate({member: true, supportedRegion: false}));
console.log(rule.evaluate({member: true, supportedRegion: true}));Expected output
false
trueChoose a design and inspect the consequence
Compare the design choices
Compare the visible consequences. With JavaScript enabled, choose an option in each scenario to assemble your decision record.
This is an exploratory design exercise. It does not run infrastructure, measure capacity or replace the lesson’s quiz.
Apply the pattern to two situations. Select one option in each situation to build a decision record. Every option and its consequence stays visible, and you can change your choices.
When it helps—and what it costs
Use it for a small stable domain language where expression composition is useful. For a complex language, a parser and established tooling may be more appropriate.
Limit nesting and evaluation work; untrusted rules can consume resources even without arbitrary code execution. Unknown fields and type mismatches need explicit behaviour. A rule result is only part of a server-side permission or eligibility decision.
Distinguish the neighbouring patterns
Visitor can supply operations over expression nodes. Strategy selects an algorithm; Interpreter represents and evaluates a language of expressions.
Follow operations on typed expression nodes, algorithm selection, server-side permission boundaries to compare the specific responsibility before combining patterns.
Check your pattern reasoning
Check your pattern reasoning
Name the responsibility before choosing the pattern
For Interpreter, describe the problem, the participating roles and the observable contract. Use the example as a starting point and test the boundaries identified in the trade-offs. A pattern name alone does not establish correctness or performance.
Return to the design-pattern guide to compare families, or apply the idea alongside server-side permission boundaries.
Reaching the recap and completing the quizzes are separate milestones.