본문 바로가기

Develop/Design Pattern

[Design Pattern] 인터프리터 (Interpreter) 패턴

728x90

1. 개요

  • 인터프리터 디자인 패턴 (Interpreter Design Pattern)은 주어진 언어나 문법에 따라 표현식을 해석하고 처리하는 패턴이다.

2. 상황

  • 언어 해석기, 컴파일러, 수식 계산기 등을 구현하고자 할 때

3. 다이어그램

interpreter-default

3.1. 설명

    • Expression
      • 표현식을 해석하기 위한 인터페이스를 정의한다.

 

    • TerminalExpression
      • Expression의 구현 클래스이다.
      • 더 이상 분해되지 않는 단일 표현식을 나타낸다.
      • 주로 터미널 기호, 변수, 상수 등으로 구성된다.

 

    • NonterminalExpression
      • Expression의 구현 클래스이다.
      • 여러 개의 하위 표현식으로 구성된 표현식을 나타낸다.
      • 주로 문법 규칙을 나타내고, 문장, 조건식 등을 해석하는 역할을 한다.

 

  • Context
    • 해석기가 처리해야 할 정보를 유지한다.
    • 표현식(Expression)의 해석이 진행될 때 상태를 공유하고 전달하는 역할을 한다.

4. 구현

public interface Expression { void interpret(); }

public class TerminalExpression implements Expression {
  private String data;
  public TerminalExpression(String data) { this.data = data; }

  @Override
  public void interpret() {
    System.out.println("Terminal Interpreting: " + data);
  }
}

public class NonterminalExpression implements Expression {
  private Expression expression;
  public NonterminalExpression(Expression expression) { 
    this.expression = expression; 
  }

  @Override
  public void interpret() {
    System.out.println("Nonterminal Interpreting");
    expression.interpret();
  }
}
public class Client {
  public static void main(String[] args) {
    Expression expression = new NonterminalExpression(
      new TerminalExpression("Hello world!")
    );
    expression.interpret();
  }
}

출력결과

Nonterminal Interpreting
Terminal Interpreting: Hello world!

5. 예시

public interface Expression { int interpret(); }

public class Number implements Expression {
  private int number;
  public Number(int number) { this.number = number; }

  @Override
  public int interpret() { return number; } 
}

public class Add implements Expression {
  private Expression left;
  private Expression right;

  public Add(Expression left, Expression right) { 
    this.left = left; 
    this.right = right; 
  }

  @Override
  public int interpret() { return left.interpret() + right.interpret(); } 
}

public class Subtract implements Expression {
  private Expression left;
  private Expression right;

  public Subtract(Expression left, Expression right) { 
    this.left = left; 
    this.right = right; 
  }

  @Override
  public int interpret() { return left.interpret() - right.interpret(); } 
}

public class Multiply implements Expression {
  private Expression left;
  private Expression right;

  public Multiply(Expression left, Expression right) { 
    this.left = left; 
    this.right = right; 
  }

  @Override
  public int interpret() { return left.interpret() * right.interpret(); } 
}
public class Client {
  public static void main(String[] args) {
    Expression plus = new Add(new Number(2), new Number(3)); // 2 + 3 = 5
    Expression minus = new Subtract(new Number(5), new Number(2)); // 5 - 2 = 3
    Expression times = new Multiply(plus, minus); // 5 * 3 = 15

    System.out.println("Result: " + times.interpret());
  }
}

 

출력결과

Result: 15

6. 장단점

6.1. 장점

  • 코드의 유연성확장성을 제공한다.
  • 간결한 객체 구조로 표현할 수 있다.
  • 복잡한 문법을 다루는 언어 해석이나 표현식 평가에 유용하다.

6.2. 단점

  • 해석 단계에서의 오버헤드가 발생할 수 있다.

관련 포스팅

728x90