728x90
반응형
Interpreter Pattern
자주 등장하는 문제를 간단한 언어로 정의하고 재사용하는 패턴
반복되는 문제 패턴을 언어 또는 문법으로 정의하고 확장할 수 있다.
BEFORE
PostfixNotation
public class PostfixNotation {
private final String expression;
public PostfixNotation(String expression) {
this.expression = expression;
}
public static void main(String[] args) {
PostfixNotation postfixNotation = new PostfixNotation("123+-");
postfixNotation.calculate();
}
private void calculate() {
Stack<Integer> numbers = new Stack<>();
for (char c : this.expression.toCharArray()) {
switch (c) {
case '+':
numbers.push(numbers.pop() + numbers.pop());
break;
case '-':
int right = numbers.pop();
int left = numbers.pop();
numbers.push(left - right);
break;
default:
numbers.push(Integer.parseInt(c + ""));
}
}
System.out.println(numbers.pop());
}
}
AFTER
APP
public class App {
public static void main(String[] args) {
PostfixExpression expression = PostfixParser.parse("xyz+-a+");
int result = expression.interpret(Map.of('x', 1, 'y', 2, 'z', 3, 'a', 4));
System.out.println(result);
}
}
PostfixParser
public class PostfixParser {
public static PostfixExpression parse(String expression) {
Stack<PostfixExpression> stack = new Stack<>();
for (char c : expression.toCharArray()) {
stack.push(getExpression(c, stack));
}
return stack.pop();
}
private static PostfixExpression getExpression(char c, Stack<PostfixExpression> stack) {
switch (c) {
case '+':
return new PlusExpression(stack.pop(), stack.pop());
case '-':
PostfixExpression right = stack.pop();
PostfixExpression left = stack.pop();
return new MinusExpression(left, right);
default:
return new VariableExpression(c);
}
}
}
PostfixExpression
public interface PostfixExpression {
int interpret(Map<Character, Integer> context);
}
VariableExpression
- 연산자가 아닌 경우 stack에 variable값을 넣어준다.
public class VariableExpression implements PostfixExpression {
private Character character;
public VariableExpression(Character character) {
this.character = character;
}
@Override
public int interpret(Map<Character, Integer> context) {
return context.get(this.character);
}
}
MinusExpression
PlusExpression
MultiplyExpression
- 연산자가 들어오는 경우 가장 마지막( 가장 오른쪽) 값과 그 앞에 있는 값을 계산해준다.
- 앞의 값에서 뒤의 값을 계산해주는 순서이기 때문에 각 연산을 할 때 순서를 맞춰준다.
public class MinusExpression implements PostfixExpression {
private PostfixExpression left;
private PostfixExpression right;
public MinusExpression(PostfixExpression left, PostfixExpression right) {
this.left = left;
this.right = right;
}
@Override
public int interpret(Map<Character, Integer> context) {
return left.interpret(context) - right.interpret(context);
}
}
public class PlusExpression implements PostfixExpression {
private PostfixExpression left;
private PostfixExpression right;
public PlusExpression(PostfixExpression left, PostfixExpression right) {
this.left = left;
this.right = right;
}
@Override
public int interpret(Map<Character, Integer> context) {
return left.interpret(context) + right.interpret(context);
}
}
public class MultiplyExpression implements PostfixExpression{
private PostfixExpression left, right;
public MultiplyExpression(PostfixExpression left, PostfixExpression right) {
this.left = left;
this.right = right;
}
@Override
public int interpret(Map<Character, Integer> context) {
return left.interpret(context) * right.interpret(context);
}
}
[패턴 복습]
장점 | 단점 |
- 자주 등장하는 문제 패턴을 언어와 문법으로 정의 가능 - 기존 코드를 변경하지 않고 새로운 Expression 추가 가능 |
- 복잡한 문법을 표현하려면 Expression과 Parser가 복잡해진다. |
생각보다 코드가 많이 복잡해지기 때문에 실제 패턴을 사용하기 위해서는 분기과정에서 선택과 집중이 필요할 듯 하다..
[실무에서 쓰이는 경우]
- 자바
- 자바 컴파일러
- 정규 표현식
- 스프링
- SpEL(스프링 Expression Language)
728x90
반응형
'Design Patterns > 행동(Behavioral)' 카테고리의 다른 글
[Memento]메멘토패턴 (0) | 2022.11.03 |
---|---|
[Mediator]중재자패턴 (0) | 2022.11.01 |
[Iterator]이터레이터패턴 (0) | 2022.10.25 |
[Command]커맨드패턴 (0) | 2022.10.20 |
[Chain-of-Responsibility]책임연쇄패턴 (0) | 2022.10.20 |