Visitor 복합객체의 연산을 수행하는 객체
알고리즘을 객체의 구조에서 분리시킨다.
-- 객체의 구조를 수정하지 않고도 실질적으로 새로운 동작을 객체 구조에 추가시킬 수 있다.
-- 컬렉션의 구조를 변하지 않고도 기능을 추가 가능하다.
-- Java에서는 Visitor Pattern을 고려하여서 사용해야 한다.
- Composite Pattern과 연계하여 사용하는 경우가 많다.
- interface IVisitor<E> {
- void visit(E e);
- }
- // 방문자 허용 인터페이스
- interface IAcceptor<E> {
- void accept(IVisitor<E> v);
- }
- class Node<E> {
- public final E data;
- public final Node<E> next;
- public Node(E data, Node<E> next) { // Object
- this.data = data;
- this.next = next;
- }
- }
- class SList<E> implements Iterable<E>, IAcceptor<E> {
- private Node<E> head;
- public SList() {
- head = null;
- }
- public void addFront(E n) {
- head = new Node<E>(n, head);
- }
- public E front() {
- return head.data;
- }
- @Override
- public Iterator<E> iterator() {
- return new SListIterator<E>(head);
- }
- // 외부로 노출되지 않기 위해 private class 로 구현하는게 일반적이다.
- @SuppressWarnings("hiding")
- private class SListIterator<E> implements Iterator<E> {
- private Node<E> current;
- public SListIterator(Node<E> node) {
- this.current = node;
- }
- @Override
- public boolean hasNext() {
- return current != null;
- }
- // 현재의 요소를 반환하며 다음으로 이동
- @Override
- public E next() {
- E value = current.data;
- current = current.next;
- return value;
- }
- @Override
- public void remove() {
- // 지원하지 않음
- throw new UnsupportedOperationException("remove() unsupported!");
- }
- }
- @Override
- public void accept(IVisitor<E> v) {
- Node<E> current = head;
- while (current != null) {
- v.visit(current.data);
- current = current.next;
- }
- }
- }
- class MovePointVisitor implements IVisitor<Point> {
- private int ax;
- private int ay;
- public MovePointVisitor(int ax, int ay) {
- this.ax = ax;
- this.ay = ay;
- }
- @Override
- public void visit(Point e) {
- e.move(this.ax, this.ay);
- }
- }
- class Point {
- private int x;
- private int y;
- public Point(int x, int y) {
- this.x = x;
- this.y = y;
- }
- public void move(int ax, int ay) {
- this.x += ax;
- this.y += ay;
- System.out.println(this.toString());
- }
- @Override
- public String toString() {
- return "Point [x=" + x + ", y=" + y + "]";
- }
- }
- // 다형성을 지원하지 않는다.
- class ShowElementVisitor<E extends Point> implements IVisitor<E> {
- @Override
- public void visit(E e) {
- e.move(10, 10); // 강하게 결합된다.
- System.out.println(e.toString());
- }
- }
- class MyPoint extends Point {
- private int z;
- public MyPoint(int x, int y, int z) {
- super(x, y);
- this.z = z;
- }
- @Override
- public String toString() {
- return "MyPoint [z=" + z + "]";
- }
- }
- //class MuliplyVisitor<E extends Integer> implements IVisitor<E> {
- //
- // @Override
- // public void visit(E e) {
- // System.out.println(e * 2); // 한계가 있다. 다형성 구현
- // }
- //
- //}
- public class Ex3 {
- public static void main(String[] args) {
- SList<Point> points = new SList<>();
- points.addFront(new Point(10, 40));
- points.addFront(new Point(20, 40));
- points.addFront(new Point(30, 30));
- points.addFront(new Point(40, 20));
- points.addFront(new Point(50, 10));
- for (Point point : points) {
- point.move(-10, -10);
- }
- points.accept(new MovePointVisitor(10, 10));
- points.accept(new ShowElementVisitor<Point>());
- SList<MyPoint> myPoints = new SList<>();
- myPoints.addFront(new MyPoint(10, 40, 1));
- myPoints.addFront(new MyPoint(20, 40, 2));
- myPoints.addFront(new MyPoint(30, 30, 3));
- myPoints.addFront(new MyPoint(40, 20, 4));
- myPoints.addFront(new MyPoint(50, 10, 5));
- }
- }
'java > design_pattern' 카테고리의 다른 글
Proxy Pattern - 대리자 패턴 (0) | 2014.07.01 |
---|---|
Iterator Pattern - 열거자 (0) | 2014.07.01 |
Chain of Responsibility Pattern - 책임의 전가 (0) | 2014.07.01 |
MediatorPattern - 중재자 패턴 (0) | 2014.07.01 |
ObserverPattern - 관찰자 패턴 (0) | 2014.07.01 |