<디자인패턴입문> 20. Interpreter 패턴
by BFine반응형
www.yes24.com/Product/Goods/2918928
가. 무엇인가
a. 문법규칙을 클래스로!
- 디자인 패턴의 목적중 하나는 클래스의 재사용성을 높이기 위한 것이다.
=> 한번 작성한 클래스를 수정(최소한)하지 않고 몇번이고 사용할 수 있도록 하는 것이다.
- 인터프리터 패턴에서는 구현하려는 문제를 간단한 미니언어로 표현한다.
=> 미니언어로 기술된 미니 프로그램으로 표현한다.
- 이 미니 프로그램은 그 자체로는 동작하지 않기 때문에 Java 언어로 통역하는 역할(interpreter)이 있어야 한다.
- 문제에 변화가 발생하면 통역역할을 수정하는 것이 아니라 미니 프로그램쪽을 수정해서 대처한다.
나. 예제
a. AbstractExpression(추상적인 표현)의 역할
- 구문의 트리의 노드에 공통의 인터페이스를 결정하는 역할이다.
public abstract class AbstractExpression {
protected abstract void interpret(Context context) throws Exception;
}
b. NonterminalExpression()의 역할
- 구문 트리의 마지막 계층이 아닌 요소들을 의미한다.
- 각각의 요소들은 체인형태로 담당 계층에 대한 처리를 하고 다른계층으로 전달한다.
public class BeginExpression extends AbstractExpression{
private final AbstractExpression abstractExpression = new LocationExpression();
public String interpret(Context context) throws Exception {
return interpret(context,"");
}
@Override
protected String interpret(Context context, String key) throws Exception {
if("위치".equals(context.nextToken())){
return abstractExpression.interpret(context,key);
}
throw new Exception("시작구문 오류");
}
}
public class LocationExpression extends AbstractExpression{
private AbstractExpression abstractExpression;
@Override
protected String interpret(Context context, String key) throws Exception {
key = context.nextToken();
String process = context.nextToken();
if("찾기".equals(process)){
abstractExpression = new FindExpression();
}
if("삭제".equals(process)){
abstractExpression = new DeleteExpression();
}
return abstractExpression.interpret(context, key);
}
}
c. TerminalExpression의 역할
- 특정한 처리루프의 마지막을 담당하며 로직뿐만 아니라 단순데이터를 리턴할수도 있다.
public class DeleteExpression extends AbstractExpression {
@Override
protected String interpret(Context context, String key) {
String productType = context.nextToken();
Map<String, List<String>> itemMap = DataBase.store.get(key);
List<String> remove = itemMap.remove(productType);
return "remove " + remove.size() + " rows";
}
}
public class FindExpression extends AbstractExpression{
@Override
protected String interpret(Context context, String key) {
String productType = context.nextToken();
Map<String, List<String>> itemMap = DataBase.store.get(key);
StringBuilder data = new StringBuilder(key).append(" : ");
List<String> productList =
itemMap.getOrDefault(productType, Collections.emptyList());
data.append(String.join(",",productList));
return data.toString();
}
}
d. Context(문맥, 전후 관계)의 역할
- 인터프리터가 구문해석을 실행하기 위한 정보를 제공하는 역할을 한다.
public class Context {
private final StringTokenizer tokens;
public Context(String wsql) {
this.tokens = new StringTokenizer(wsql);
}
public String nextToken(){
return tokens.nextToken();
}
}
e. Main (Client)
public class Main {
public static void main(String[] args) throws Exception {
Scanner scanner = new Scanner(System.in);
for (int testIndex = 0; testIndex < 3; testIndex++) {
String input = scanner.nextLine();
// 시스템입력 : 위치 [제조사] 찾기 [분류]
Context context = new Context(input);
BeginExpression beginExpression = new BeginExpression();
System.out.println(beginExpression.interpret(context));
}
}
}
/**
"C:\Program Files\Java\jdk1.8.0_251\bin\java.exe"
위치 samsung 찾기 tablet
samsung : gtab S7,gtab A7
위치 apple 찾기 phone
apple : iphone se,iphone 12
위치 apple 삭제 phone
remove 2 rows
*/
다. 정리
a. 건너 뛸까, 읽을까
- 자주 발생하는 문제는 토큰을 많이 읽거나 혹은 적게 읽는 경우이다.
=> 항상 어디까지 토큰을 읽었는지, 어디까지 읽을 것인지를 염두에 두고 있어야한다.
interpreter 패턴은 어떠한 문제를 언어로 보고 해당 키워드를 클래스화하여 문제를 처리하는 패턴이다.
반응형
'개발서적 > 디자인패턴입문' 카테고리의 다른 글
<디자인패턴입문> 19. Command 패턴 (0) | 2021.05.12 |
---|---|
<디자인패턴입문> 18. Proxy 패턴 (0) | 2021.05.11 |
<디자인패턴입문> 17. Flyweight 패턴 (0) | 2021.05.10 |
<디자인패턴입문> 16. State 패턴 (0) | 2021.05.09 |
<디자인패턴입문> 15. Memento 패턴 (0) | 2021.05.08 |
블로그의 정보
57개월 BackEnd
BFine