본문 바로가기
Programming

디자인패턴 시리즈 14. 인터프리터 패턴 (Interpreter Pattern)

by LeeJ1Hyun 2023. 1. 30.

인터프리터 패턴 (Interpreter Pattern)

자주 등장하는 문제를 간단한 언어로 정의하고 재사용한다.

코드에 적용해보기

언어로 정의한다는 말은 약속을 한다는 뜻이다. 예를 들어 1 add 1은 피연산자: 1, 연산자: +, 피연산자: 1로 해석된다. add라는 명령을 사용했을 때 약속된대로 이를 해석하는 패턴이 바로 인터프리터 패턴이다. 대표적인 예시로 정규표현식이 있다. 일종의 패턴을 만들어 \d는 숫자를 의미하고, ^A는 A로 시작한다는 의미이다. 매번 문자열에서 어떤 패턴을 찾는 로직을 만드는 것보단 규칙을 정의하고 이를 해석하는 것이 더 낫다고 판단했기 때문이다.

 

다만 이를 남발하는 것은 좋지 않다. 인터프리터 패턴은 언어의 문법이 복잡해질수록 관리할 클래스가 많아져 오히려 복잡해진다.

 

인터프리터 패턴 다이어그램

 

  • Context : 모든 Expression에서 사용하는 공통 정보가 존재
  • Expression : 표현하는 문법을 나타냄
  • TerminalExpression : 종료되는 Expression
  • NonterminalExpression : 다른 Expression을 재귀적으로 참조하고 있는 Expression

 

인터프리터 패턴으로 후위표기법을 구현해보자. 후위표기법은 AB+의 형태로 피연산자를 먼저 표시하고 연산자를 나중에 표시하는 방법이다. 예를 들어 13+는 우리가 알고있는 1 더하기 3이다. 컴파일러가 사용하는 것으로 스택을 사용하는 예시이다.

 

public interface Expression {

    int interpret(Map<Character, Integer> context);
}

 

후위표기법의 표현 문법을 나타낼 Expression 인터페이스를 생성한다. AB+의 형태에 13+를 대입한 것처럼 Map<Character, Integer> 데이터 구조를 활용하여 A가 1임을 전달할 것이다.

 

public class PlusExpression implements Expression {

    private Expression left;

    private Expression right;

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

    @Override
    public int interpret(Map<Character, Integer> context) {
        return left.interpret(context) + right.interpret(context);
    }
}

 

public class MinusExpression implements Expression {

    private Expression left;

    private Expression right;

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

    @Override
    public int interpret(Map<Character, Integer> context) {
        return left.interpret(context) - right.interpret(context);
    }
}

 

Expression 인터페이스를 상속 받은 NonterminalExpression인 PlusExpression, MinusExpression 구상 클래스는 interpret 메소드를 구현한다.

 

public class VariableExpression implements Expression {

    private Character character;

    public VariableExpression(Character character) {
        this.character = character;
    }

    @Override
    public int interpret(Map<Character, Integer> context) {
        return context.get(this.character);
    }
}

 

TerminalExpression인 VariableExpression 클래스는 값을 그대로 반환하는 종료 Expression이다.

 

public class PostfixParser {

    public static Expression parse(String expression) {
        Stack<Expression> stack = new Stack<>();
        for (char c : expression.toCharArray()) {
            stack.push(getExpression(c, stack));
        }
        return stack.pop();
    }

    private static Expression getExpression(char c, Stack<Expression> stack) {
        switch (c) {
            case '+':
                return new PlusExpression(stack.pop(), stack.pop());
            case '-':
                Expression right = stack.pop();
                Expression left = stack.pop();
                return new MinusExpression(left, right);
            default:
                return new VariableExpression(c);
        }
    }
}

 

후위표기법의 계산 방식대로 파싱해주는 PostfixParser 클래스는 parse() 메소드로 받은 문자열을 character로 하나씩 쪼갠뒤 getExpression() 메소드로 stack에 넣는다.

 

public class Client {

    public static void main(String[] args) {
        Expression expression = PostfixParser.parse("xyz+-");
        int result = expression.interpret(Map.of('x', 1, 'y', 2, 'z', 3));
        System.out.println(result);
    }
}

 

xyz+-는 (z + y) - x 이므로 실행하면 -4라는 결과가 나온다. 디버깅을 통해 구조를 살펴보면 트리 구조를 띄고 있다.

 

 

Sql의 실행 로직도 인터프리터 패턴을 통해 구현할 수 있다. 하지만 앞서 말했듯이 규칙이 복잡해질수록 클래스의 개수가 많아지고 Expression, parser도 함께 복잡해지기 때문에 적절한 상황에 사용하는 것이 중요하다.

 

 

 

 

 

* 아래의 자료들을 참고하였습니다.

 

15. 인터프리터 패턴 (interpreter pattern)

인터프리터 패턴 (CS에서는 사람이 작성한 코드를 하드웨어가 이해할 수 있도록 변환해주는 장치를 인터프리터라고 한다.) 자주 등장하는 문제 🔜 간단한 언어 로 정의하고 재사용하는 패턴 -->

kingchan223.tistory.com

 

15. 인터프리터 패턴

1. 의미 인터프리터(interpreter) 사전적 의미 → 통역, 연주자 자주 등장하는 문제를 간단한 언어로 정의하여 재사용하는 패턴 반복되는 문제 패턴을 언어 또는 문법으로 정의하고 확장 패턴이나

jinn-blog.tistory.com

 

[디자인패턴] Interpreter Pattern 인터프리터패턴

문장을 해석할 때 사용하는 패턴. 해석기, 즉 간이언어를 만들기 위한 패턴. 언어 문법이나 표현을 평가할 수 있는 방법을 제공. (행동패턴) 특정 컨텍스트를 해석하도록 지시하는 표현 인터페이

httt.tistory.com

댓글