인터프리터(Interpreter) 패턴 : 행위패턴
문법규칙을 클래스로 표현한 구조, 일련의 규칙으로 정의된 문법적 언어를 해석하는 패턴
해석자 패턴이라고도 불린다. 반복되는 문제 패턴을 언어 또는 문법으로 정의한다.
자바소스 코드를 JVM이 이해할 수 있도록 바이트 코드로 바꿔주는 자바 컴파일러와 정규 표현식이 대표적인 예시이다.
Context : Expression에서 사용하는 공통된 정보가 담겨있다. 문장을 저장하고 관리하는 클래스
Expression: 표현하는 문법을 나타낸다. Context가 들어 있는 것을 볼 수 있다.
TerminalExpression: 종료되는 Expression
NonTerminalExpression: Expression들을 재귀적으로 참조하고 있는 Expression, 문장의 비종료를 나타내는 해석자 클래스 구현체
인터프리터 패턴의 장단점
장점
- 스크립트 언어 및 프로그래밍 언어에서 모두 사용이 가능하며, 문법을 클래스로 표현해서 쉽게 언어를 구현할 수 있다.
- 문법의 추가 및 수정, 구현이 쉬워진다.
단점
- 여느 패턴이 그렇듯 문법 규칙의 개수가 많아지면 아주 복잡해진다는 단점이 있다.
- 복잡한 문법의 경우 관리 및 유지가 어렵다.
인터프리터 패턴의 예시
Expression
public interface Expression {
String interpret(InterpreterContext ic);
}
AddExpression
public class AddExpression implements Expression{
private int a;
private int b;
public AddExpression(int a, int b) {
this.a = a;
this.b = b;
}
@Override
public String interpret(InterpreterContext ic) {
return ic.getAdd(a, b);
}
}
SubExpression
public class SubExpression implements Expression{
private int a;
private int b;
public SubExpression(int a, int b) {
this.a = a;
this.b = b;
}
@Override
public String interpret(InterpreterContext ic) {
return ic.getSub(a, b);
}
}
IntToBinaryExpression
public class IntToBinaryExpression implements Expression {
private int i;
public IntToBinaryExpression(int i) {
this.i = i;
}
@Override
public String interpret(InterpreterContext ic) {
return ic.getBinaryFormat(i);
}
}
IntToHexExpression
public class IntToHexExpression implements Expression {
private int i;
public IntToHexExpression(int i) {
this.i = i;
}
@Override
public String interpret(InterpreterContext ic) {
return ic.getHexadecimalFormat(i);
}
}
InterpreterContext
public class InterpreterContext {
public String getBinaryFormat(int i) {
return Integer.toBinaryString(i);
}
public String getHexadecimalFormat(int i) {
return Integer.toHexString(i);
}
public String getAdd(int a, int b){
return String.format("%d",a+b);
}
public String getSub(int a, int b){
return String.format("%d",a-b);
}
}
Clinet
System.out.println("-".repeat(20) + "인터프리터 패턴 easy 테스트" + "-".repeat(20));
String str1 = "28 의 2진수 ";
String str2 = "28 의 16진수 ";
String str3 = "ADD 3 5 ";
String str4 = "SUB 5 3 ";
InterpreterClient T = new InterpreterClient();
System.out.println(str1+"= "+T.interpret(str1));
System.out.println(str2+"= "+T.interpret(str2));
System.out.println(str3+"= "+T.interpret(str3));
System.out.println(str4+"= "+T.interpret(str4));
public String interpret(String str) {
InterpreterContext ic = new InterpreterContext();
Expression exp = null;
String[] arr = str.split(" ");
if(str.contains("16진수")) {
exp = new IntToHexExpression(Integer.parseInt(arr[0]));
} else if(str.contains("2진수")) {
exp = new IntToBinaryExpression(Integer.parseInt(arr[0]));
} else if(str.contains("ADD")){
exp = new AddExpression(Integer.parseInt(arr[1]), Integer.parseInt(arr[2]));
} else if(str.contains("SUB")){
exp = new SubExpression(Integer.parseInt(arr[1]), Integer.parseInt(arr[2]));
}
else return str;
return exp.interpret(ic);
}
공부했던 디자인 패턴 중에서 제일 난해하게 받아들인 디자인 패턴이었다.
내가 이해한 식으로 표현을 해보자면, NonTerminalExpression에서 해석해야 될 정보를 계층적으로 쌓아가며 문장을 해석하고, TerminalExpression에서 스트림의 최종 연산자처럼 문장의 끝을 알려주는 역할(?)을 하며, Context에서 서비스 로직처럼 실질적으로 정보를 처리한다고 이해했다.
이걸 실무에 어떻게 적용할지는 직접 실무 소스를 접해봐야 알 것 같다.
Reference
https://donghyeon.dev/design%20pattern/2020/05/29/Interpreter-%ED%8C%A8%ED%84%B4/
'OOP > Design Pattern' 카테고리의 다른 글
16. 중재자(Mediator) 패턴 (0) | 2023.02.21 |
---|---|
15. 이터레이터(iterator) 패턴 (0) | 2023.02.21 |
13. 커맨드(Command) 패턴 (0) | 2023.02.20 |
12. 프록시(Proxy) 패턴 (0) | 2023.02.20 |
11. 플라이웨이트(Flyweight) 패턴 (0) | 2023.02.20 |