인터프리터 패턴

GoF의 디자인패턴 중 행동의 인터프리터 패턴을 Java 로 정리한 글

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

반복되는 문제 패턴을 언어 또는 문법으로 정의하고 확장할 수 있다.

Interpreter Design Pattern

종료되는 표현식, 종료되지 않는 표현식(다른 표현식을 참조하는 표현식) 을 바탕으로 섞어서 현 문장을 해석하는 방식으로 진행되어진다.

UML을 보자면 다음과 같은데,

Interpreter Pattern | 밥줄과 취미 사이 ːː 못 먹어도 고!

어떠한 해석을 정의하여 특정 값이 왔을 때 정의된 해석에 따라 결과를 도출하는 패턴이라 볼 수 있다.

  • AbstractExpression : 모든 표현에서 공통적으로 사용할 interpret()를 정의한 추상클래스

  • TerminalExpression : 표현에서 사용되는 기호들(x,y,z)의 해석값을 구하는 클래스(즉 x일때 무엇, y일때 무엇, z일때 무엇으로 해석하나)

  • NonterminalExpression : 기호만으로는 결과가 나오지 않고 특정 Expression들을 참조해서 결과를 얻어야하는 클래스(+, -만으로는 결과가 나오지 않고 z, x, y과 같은 TerminalExpression, 또는 또 다른 NontermialExpresion 참조해서 결과값을 얻을 때까지 재귀적으로 참조한다. )

  • Context : 표현을 분석할 때 사용될 포괄적인 정보

  • Client : 언어로 정의한 특정 문장을 나타내는 클래스. interpret()를 호출하는 클래스

1. 예시 코드

결국 이 패턴은 정말 특정 언어(SQL)를 해석할 때에만 크게 효율적인 패턴이라는 것을 알 수 있다.

AST트리 형태로 해석하는 것에 도움을 주는 방식이다.

컴포짓 패턴과 상당히 유사하게 생김. 즉, 이 표현식 방식이 결국 트리구조를 가지게 되는 형태이다.

컴포짓도 컴포넌트안에 컴포넌트가 아래로 계속 존재하게 되고 트리구조처럼 이뤄지는 면에서는 또 인터프리터 패턴이 또 유사한 점이 있다.

컴포짓은 컴포넌트에 재귀형식으로 구현되어있다면, 인터프리터 패턴은 non-terminalExpression이 재귀형식으로 내려가고 Leaf 역할을 terminalExpression이 역할을 대체하는 것 같다.

2. 장점 / 단점

장점

  • 자주 사용하는 패턴을 우리만의 문법으로 정의해서 재사용할 수 있음

  • 기존 코드 변경하지 않고 새로운 Expression 만드는 것이 가능 (OCP)

단점

  • 너무 복잡함

  • 문법이 복잡하면, 구현이 어려움.

  • 구성 가성비가 떨어질수도 있음. 굳이... 이게 정말 필요한지에 대해서 잘 판단해서 구현하는게 좋을 수 있다.

3. 어디에서 쓰는지?

자바

  • Compiler

  • Regex ⇒ Pattern.matches()

스프링

Spring Expression Language ⇒ SpEL

파서가 따로있고, 그 컴파일러도 존재

여기서 대부분의 표현식이 컴파일링 된다.

Last updated