Interpreter pattern : interpreter 구현 구조를 OOP에 맞게 표현한 형태이다. 주로 특화된 언어나 프로토콜등 규칙에 따라 해석되는 언어의 해석기(interpreter)를 구조화 할 때 사용된다.
언어를 해석할때는 BNF(Backus Naur Form) 형태로 나타내는 경우가 많다. 대부분의 언어 구조가 이 형태로 표현할 수 있기 때문인데, 그렇기 때문에 Interpreter pattern도 BNF 구조의 언어를 해석하기에 알맞은 해석기를 표현할 수 있게끔 디자인되었다.
BNF에서 Terminal expression 과 Non-Terminal expression이 존재한다. 그리고 하나의 문장은 BNF구조의 최상위 루트의 expression을 나타낸다. Interpreter pattern은 이 구조에 맞게 Expression을 나타내는 인터페이스와 이를 상속하여 말단표현을 나타내거나 비말단 표현을 나타내는 클래스를 파생한다. 이런 구조때문에 Interpreter pattern은 Composite pattern을 모방한다고 볼 수 있다.
위와 같은 구조를 가지며(Composite pattern과 똑같다.) 클라이언트는 상위 추상클래스(혹은 인터페이스)를 통하여 Context를 해석할 수 있다. 일반적으로 Interpreter pattern에서는 parser를 정의하지 않지만, 필요에 디자인 구조에 포함하기도 한다.
영어의 문장 형식을 다음과 같이 BNF로 표현했을 때,
<sentence> ::= <fmt_1> | <fmt_2> | <fmt_3> | <fmt_4> | <fmt_5>
<fmt_1> ::= <subject> <verb> | <subject> <verb> <predicate>
<fmt_2> ::= <subject> <verb> <subjective_complement> | <subject> <verb> <subjective_complement> <predicate>
...
<subject> ::= <noun> | <supine> | <gerund> | <that_clause> | <what_clause> | ... //(definite articles)
<that_clause> ::= that <subject> <verb>
<what_clause> ::= what <verb> | what <subject> <verb>
...
모두 표현하자면 끝도 없으니, 적당히 끊고. 이를 Interpreter pattern을 적용하여 해석기 모델을 설계해 보았다. 구조를 익히기 위한 예제라 별 의미는 없지만, 패턴이 어떤식으로 적용되는지는 볼 수 있을것이다.
public abstract class Expression {
protected String rawString;
public abstract String interpret(Dictionary dic);
}
public class Dictionary {
public class Voca{
public String name;
public Class<?> type;
}
private Map<String, Voca> dictionary;
public Dictionary(){
dictionary = new HashMap<String, Voca>();
}
public String findMeaning(String key){
return dictionary.get(key).name;
}
public Class<?> checkType(String key){
return dictionary.get(key).type;
}
}
public class Sentence extends Expression {
private Expression root;
public Sentence(String sentence){
rawString = sentence;
}
private void parse(Dictionary dic){
// ...
}
@Override
public String interpret(Dictionary dic) {
parse(dic);
return root.interpret(dic);
}
}
public class Format1Sentence extends Expression {
private Expression subject;
private Expression verb;
private Expression predicate;
public Format1Sentence(Expression subject, Expression verb, Expression predicate){
this.subject = subject;
this.verb = verb;
this.predicate = predicate;
}
@Override
public String interpret(Dictionary dic) {
if(predicate != null)
return subject.interpret(dic) + verb.interpret(dic) + predicate.interpret(dic);
else
return subject.interpret(dic) + verb.interpret(dic);
}
}
public class Subject extends Expression {
private Expression definiteArticle; //정관사
public Subject(Expression definiteArticle){
this.definiteArticle = definiteArticle;
}
@Override
public String interpret(Dictionary dic) {
return definiteArticle.interpret(dic);
}
}
'Coding Note' 카테고리의 다른 글
[Design pattern] Memento (0) | 2013.03.26 |
---|---|
[Design pattern] Mediator (0) | 2013.03.25 |
[Design pattern] Proxy (1) | 2013.03.07 |
[Design pattern] Flyweight (3) | 2013.03.05 |
[Design pattern] Facade (0) | 2013.03.04 |