인터프리터 패턴이란?
- 특정 언어의 문법을 정의하고 해석하는 패턴
- 특정 문법(표현식)을 해석할 수 있는 클래스를 설계하는 방식으로, 언어의 구문을 처리하거나 계산식을 평가하는 데 사용
구성 요소
1. Abstract Expression (추상 표현식)
모든 표현식(Expression)이 구현해야 할 인터페이스를 정의
2. Terminal Expression (터미널 표현식)
기본적인 표현식(숫자, 변수 등)을 정의하고, 해석하는 클래스
3. Non Terminal Expression (비터미널 표현식)
터미널 표현식들을 조합하여 더 복잡한 표현식을 구성하는 클래스
4. Context (문맥, 환경 클래스)
해석에 필요한 정보를 저장하는 클래스
연산자(+, -, *, /) 같은 역할을 수행
5. Client (클라이언트 코드)
표현식을 구성하고 해석기(Interpreter)를 실행하는 코드
패턴 흐름
1. 입력된 표현식을 분석하여 터미널 및 비터미널 표현식을 구성
2. 터미널 표현식은 기본 숫자 값(숫자, 변수 등)을 해석
3. 비터미널 표현식은 터미널 표현식들을 조합하여 해석 수행
4. Context 객체를 사용하여 필요한 정보(변수 값, 연산 결과 등)을 저장
5. interpret() 메서드를 실행하여 최종 결과 얻음
인터프리터 패턴 예제 (C++)
1. #include <iostream>
2. #include <string>
3. #include <map>
4.
5. using namespace std;
6.
7. // 1. AbstractExpression (추상 표현식)
8. class Expression {
9. public:
10. virtual int interpret(map<string, int>& context) = 0;
11. virtual ~Expression() {}
12. };
13.
14. // 2. TerminalExpression (터미널 표현식, 숫자/변수 해석)
15. class NumberExpression : public Expression {
16. private:
17. int number;
18.
19. public:
20. NumberExpression(int number) : number(number) {}
21.
22. int interpret(map<string, int>& context) override {
23. return number;
24. }
25. };
26.
27. // 3. TerminalExpression (변수 해석)
28. class VariableExpression : public Expression {
29. private:
30. string name;
31.
32. public:
33. VariableExpression(string name) : name(name) {}
34.
35. int interpret(map<string, int>& context) override {
36. return context[name]; // 변수 값을 Context에서 가져옴
37. }
38. };
39.
40. // 4. NonTerminalExpression (비터미널 표현식, 덧셈)
41. class AddExpression : public Expression {
42. private:
43. Expression* left;
44. Expression* right;
45.
46. public:
47. AddExpression(Expression* left, Expression* right) : left(left), right(right) {}
48.
49. int interpret(map<string, int>& context) override {
50. return left->interpret(context) + right->interpret(context);
51. }
52. };
53.
54. // 5. NonTerminalExpression (비터미널 표현식, 뺄셈)
55. class SubtractExpression : public Expression {
56. private:
57. Expression* left;
58. Expression* right;
59.
60. public:
61. SubtractExpression(Expression* left, Expression* right) : left(left), right(right) {}
62.
63. int interpret(map<string, int>& context) override {
64. return left->interpret(context) - right->interpret(context);
65. }
66. };
67.
68. // 6. Client (클라이언트 코드)
69. int main() {
70. // Context (변수 값 저장)
71. map<string, int> context;
72. context["x"] = 10;
73. context["y"] = 5;
74.
75. // 표현식 생성: (x + y) - 3
76. Expression* expression = new SubtractExpression(
77. new AddExpression(
78. new VariableExpression("x"),
79. new VariableExpression("y")
80. ),
81. new NumberExpression(3)
82. );
83.
84. // 해석(Interpret) 수행
85. cout << "(x + y) - 3 = " << expression->interpret(context) << endl; // 결과: 12
86.
87. // 메모리 해제
88. delete expression;
89.
90. return 0;
91. }
92.
인터프리터 패턴 장점
1. 새로운 연산자나 표현식 쉽게 추가 가능
2. 언어 해석 로직을 객체지향적으로 설계
3. 복잡한 문법을 계층적으로 구성 가능
인터프리터 패턴 단점
1. 표현식이 복잡해질수록 클래스의 수가 많아지고 성능 저하 유발
2. 간단한 언어 해석에는 적합하지만, 복잡한 프로그래밍 언어 해석하는데 적절하지 않음
3. 표현식을 개별 클래스로 분리하다 보면 클래스 개수 증가
'Unity > 디자인 패턴' 카테고리의 다른 글
| 디자인 패턴 (행위 패턴) - 옵저버 패턴 (Observer Pattern) (0) | 2025.08.30 |
|---|---|
| 디자인 패턴 (행위 패턴) - 이터레이터 패턴 (Iterator Pattern) (0) | 2025.08.30 |
| 디자인 패턴 (행위 패턴) - 커맨드 패턴 (Command Pattern) (0) | 2025.08.30 |
| 디자인 패턴 (구조 패턴) - 프록시 패턴 (Proxy Pattern) (0) | 2025.08.30 |
| 디자인 패턴 (구조 패턴) - 플라이웨이트 패턴 (Flyweight Pattern) (0) | 2025.08.30 |