public class Clock
{
public void tick()
{
publisher.publish
(
//Clock이 생성한 Distributor 구현은 Concrete Visitor
new Publisher.Distributor()
{
public void deliverTo( Object subscriber )
{
if( !menuIsActive() )
((Listener)subscriber).tick();
}
}
);
}
}
public class Publisher
{
public interface Distributor
{
void deliverTo( Object subscriber ); // the Visitor pattern's
} // "visit" method.
private volatile Node subscribers = null;
public void publish( Distributor deliveryAgent )
{
for(Node cursor = subscribers; cursor != null; cursor = cursor.next)
cursor.accept( deliveryAgent );
//deliveryAgent.deliverTo( subscriber ); // a "visitor"
}
synchronized public void subscribe( Object subscriber )
{
subscribers = new Node( subscriber, subscribers );
}
synchronized public void cancelSubscription( Object subscriber )
{
subscribers = subscribers.remove( subscriber );
}
}
private class Node
{
public final Object subscriber;
public final Node next;
private Node( Object subscriber, Node next )
{
this.subscriber = subscriber;
this.next = next;
}
public Node remove( Object target )
{
if( target == subscriber )
return next;
if( next == null ) // target is not in list
throw new java.util.NoSuchElementException
(target.toString());
return new Node(subscriber, next.remove(target));
}
{
deliveryAgent.deliverTo( subscriber ); // a "visitor"
}
}
- Clock : 클라이언트 객체
- Publisher는 Object Structure
- Distributor는 Visitor 인터페이스
- Node는 객체 구조 안에 포함되어 있는 Element
- Node.accept() : 'Accept) 요청
- deliverTo() : 'visit' 요청이다.
- Clock이 생성한 Distributor 구현은 Concrete Visitor
주로 호스트 객체는 자료 구조로 구성되어 있으며 Visitor는 이 자료 구조를 순회하며 호스트 객체를 방문/처리 한다.
Visitor 패턴 장점
- Visitor는 기존 객체를 변경하지 않으면서 새로운 연산을 추가할 수 있도록 해준다
- 이는 구현 시에 생각하지 못했던 혹은 알려지지 않았던 연산을 쉽게 구현할 수 있도록 해준다.
- 드물게 사용되는 연산을 외부에 구현할 수 있도록 해주기 때문에 클래스가 작아진다.
Visitor 패턴 주의 사항
- Visotor는 캡슐화를 위반 할수도 있으며, Visitor와 Element 사이의 결합도가 높다.
- 가능하면 Visitor가 Element의 Public 인터페이스 혹은 제한된 인터페이스를 접근하도록 하자
이 패턴 잘 이해가 안간다. 다시 공부해야 한다.^^