비지터 패턴으로 변경 가능성이 높은 부분을 개발해보자.
파싱트리를 만드는 것에 대해서 배운 적은 없다. 제대로 만들어 본 적이 없기 때문에 한 번쯤은 제대로 배워보고 싶은 생각이 드는데 어디서 부터 공부를 해야 할지 아직도 잘 모르겠다.일단 우리는 산술식을 다양한 방법으로 표현할 것이다. 이 식을 표현식이라고 부르자.
이 표현식으로 쪼개고 쪼개서 토큰화 시키고 그 수식들을 그대로 문자열로 보이도록 하거나, 계산을 해서 답을 내도록 해보자.
표현식은 BNF로 표현했다고 하자.
비지터패턴으로 만들 것이다.
1. 비지터 인터페이스 생성.
interface Visitor{ R plus(Expr e1, Expr e2); // 덧셈 식을 위한 메소드 R square(Expr e); // 제곱 식을 위한 메소드 R number(N n); // 숫자를 위한 메소드 }
2. 표현식 인터페이스 생성 및 구현
interface Expr{ R accept(Visitor v); class Plus implements Expr { Expr e1; Expr e2; public Plus(Expr e1, Expr e2) { this.e1 = e1; this.e2 = e2; } @Override public R accept(Visitor v) { return v.plus(e1, e2); } } class Square implements Expr { Expr e; public Square(Expr e) { this.e = e; } @Override public R accept(Visitor v) { return v.square(e); } } class Number implements Expr { N n; public Number(N n) { this.n = n; } @Override public R accept(Visitor v) { return v.number(n); } }
3. 비지터 패턴을 구현
// 식의 평가를 실시하는 Visitor class Eval implements Visitor{ @Override public Integer plus(Expr e1, Expr e2) { return e1.accept(this) + e2.accept(this); } @Override public Integer square(Expr e) { Integer x = e.accept(this); return x; } @Override public Integer number(Integer n) { return n; } } // 식을 문자열로 하는 Visitor class Show implements Visitor { @Override public String plus(Expr e1, Expr e2) { return e1.accept(this) + " + " + e2.accept(this); } @Override public String square(Expr e) { return "(" + e.accept(this) + ")^2"; } @Override public String number(Integer n) { return n + ""; } }
이제 실행해보자.
public class TestVisitor { public static void main(String[] args) { // e = 1 + (2 + 3) ^ 2 // 실제로는 구문 해석 등에 의해서 좀 더 크고 복잡한 것을 가정 Expr e = new Plus(new Number(1), new Square(new Plus(new Number(2) ,new Number(3)))); System.out.println(e.accept(new Show())); System.out.println(e.accept(new Eval())); } }
이 프로그램과 설계에는 문제가 없음.
변경에 대한 유연성에 대해서도 다음과 같은 경우에 따라 각각 가산해서 대응할 수 있으므로 Visitor 패턴을 사용하는 것은
객체지향 프레임워크로서는 더할 나위 없는 방법이라고 말할 수 있다.
- 식의 증가에 대해 (뺄셈의 추가)
a. Visitor의 메소드를 늘린다.
b. 식의 인터페이스를 계승하는 클래스를 늘린다.
- 식에 대한 처리 종류의 증가에 대해 (JSON으로 변경)
a. Visitor를 계승하는 클래스를 늘린다.
이런식으로 계속 계산식 혹은 처리방식을 추가할 때, 객체지향적인 방법으로 추가를 할 수 있게 된다.
댓글 없음:
댓글 쓰기