Interpreter Design Pattern in Java
Learn Interpreter Design Pattern in Java with expression trees, business rule engines, DSLs, Spring Expression Language (SpEL), real-world examples, UML diagrams, and interview questions.
What You Will Learn
- What is Interpreter Pattern?
- Why Interpreter Pattern is Needed
- Grammar and Expressions
- Expression Trees
- Rule Engines
- DSL (Domain Specific Language)
- Spring Expression Language (SpEL)
- Java Implementation
- Enterprise Use Cases
- Benefits and Limitations
- Interview Questions
What is Interpreter Pattern?
Interpreter is a Behavioral Design Pattern that defines a grammar and provides a mechanism to interpret sentences in that grammar.
Think of it as:
Expression
↓
Interpreter
↓
Result
Why Do We Need It?
Suppose a banking application has rules like:
Age > 18
Credit Score > 700
Income > 50000
Without Interpreter:
if(age > 18 &&
creditScore > 700 &&
income > 50000) {
approveLoan();
}
Every rule change requires code deployment.
Interpreter allows rules to be represented as expressions.
Real World Examples
- SQL Parsers
- Search Query Engines
- Rule Engines
- Spring Expression Language (SpEL)
- Feature Flags
- Access Control Rules
- Workflow Engines
Interpreter Architecture
flowchart LR
A[Expression]
B[Parser]
C[Interpreter]
D[Result]
A --> B
B --> C
C --> D
Key Components
Expression
Common interface.
public interface Expression {
boolean interpret(Context context);
}
Terminal Expression
Represents a simple condition.
Example:
Age > 18
Non-Terminal Expression
Combines expressions.
Example:
Age > 18
AND
Income > 50000
Context
Contains data required for evaluation.
UML Diagram
classDiagram
class Expression {
+interpret()
}
class AgeExpression
class IncomeExpression
class AndExpression
class Context
Expression <|.. AgeExpression
Expression <|.. IncomeExpression
Expression <|.. AndExpression
Loan Approval Example
Business Rule:
Age > 18
AND
Income > 50000
Processing Flow
flowchart LR
A[Age Rule]
B[Income Rule]
C[AND Expression]
D[Result]
A --> C
B --> C
C --> D
Step 1: Context Object
public class UserContext {
private int age;
private double income;
public UserContext(
int age,
double income) {
this.age = age;
this.income = income;
}
public int getAge() {
return age;
}
public double getIncome() {
return income;
}
}
Step 2: Expression Interface
public interface Expression {
boolean interpret(
UserContext context);
}
Step 3: Age Expression
public class AgeExpression
implements Expression {
@Override
public boolean interpret(
UserContext context) {
return context.getAge() > 18;
}
}
Step 4: Income Expression
public class IncomeExpression
implements Expression {
@Override
public boolean interpret(
UserContext context) {
return context.getIncome() > 50000;
}
}
Step 5: AND Expression
public class AndExpression
implements Expression {
private Expression left;
private Expression right;
public AndExpression(
Expression left,
Expression right) {
this.left = left;
this.right = right;
}
@Override
public boolean interpret(
UserContext context) {
return left.interpret(context)
&& right.interpret(context);
}
}
Client Code
public class InterpreterDemo {
public static void main(
String[] args) {
UserContext context =
new UserContext(
25,
60000);
Expression ageRule =
new AgeExpression();
Expression incomeRule =
new IncomeExpression();
Expression rule =
new AndExpression(
ageRule,
incomeRule);
System.out.println(
rule.interpret(context));
}
}
Output
true
Execution Flow
sequenceDiagram
Client->>AgeExpression: interpret()
AgeExpression-->>Client: true
Client->>IncomeExpression: interpret()
IncomeExpression-->>Client: true
Client->>AndExpression: combine()
AndExpression-->>Client: true
Banking Example
Loan Rules:
Age > 18
Credit Score > 700
Income > 50000
Interpreter evaluates the rule dynamically.
flowchart LR
A[Loan Rules]
B[Interpreter]
C[Decision]
A --> B
B --> C
Insurance Example
Claim Rules:
Policy Active
Claim Amount < 100000
No Fraud
flowchart LR
A[Claim]
B[Rule Engine]
C[Interpreter]
D[Approval]
A --> B
B --> C
C --> D
Spring Example
Spring Expression Language (SpEL)
@Value("#{systemProperties['user.name']}")
private String userName;
Spring interprets the expression at runtime.
Feature Flag Example
Country = USA
AND
Premium User = true
Interpreter determines whether a feature should be enabled.
flowchart LR
A[Feature Rule]
B[Interpreter]
C[Feature Enabled]
A --> B
B --> C
Enterprise Architecture
flowchart LR
A[Business Rules]
B[Parser]
C[Expression Tree]
D[Interpreter]
E[Decision Engine]
F[Application]
A --> B
B --> C
C --> D
D --> E
E --> F
Benefits
✅ Dynamic Business Rules
✅ Eliminates Large If-Else Blocks
✅ Easy To Extend
✅ Supports DSL Creation
✅ Works Well For Rule Engines
✅ Improves Maintainability
Limitations
❌ Large Grammar Creates Many Classes
❌ Complex Rules Can Become Hard To Manage
❌ Performance Overhead For Very Large Expression Trees
Where Is It Used?
- Spring Expression Language (SpEL)
- Drools Rule Engine
- SQL Parsers
- Search Engines
- Workflow Engines
- Feature Flag Platforms
- Security Authorization Rules
Interview Questions
What is Interpreter Pattern?
A behavioral pattern used to define and evaluate a grammar or expression language.
What is a Terminal Expression?
A simple expression that cannot be broken further.
What is a Non-Terminal Expression?
An expression composed of multiple expressions.
Real Java Example?
Spring Expression Language (SpEL).
Enterprise Examples?
Rule Engines, SQL Parsers, Workflow Systems, Feature Flags.
Key Takeaways
- Interpreter is a Behavioral Design Pattern.
- It converts business rules into executable expressions.
- Uses Expression Trees (AST).
- Common in Rule Engines and DSLs.
- Spring SpEL is a real-world implementation.
- Excellent for configurable business rules.