2009-08-26 2 views

답변

11

아니요, 아니요, 목표 -C 카테고리는 방문자 패턴을 구현하지 않습니다. 대부분의 언어에서는 하위 클래스가없는 기존 클래스에 메소드를 삽입하는 기술이 없으므로 카테고리는 디자인 패턴 세계에서 정확히 일치하지 않습니다. 나는 그것이 decorator pattern에 더 가깝다고 말하고 싶지만, 그 패턴은 일반적으로 합성으로 구현됩니다. 즉, "강화"하고 싶은 오브젝트의 인스턴스를 래핑하면됩니다.

visitor 패턴은 다양한 객체, 구조체 등에 적용될 수있는 알고리즘 로직을 캡슐화하는 데 유용합니다. 예를 들어, 객체 그래프에 대한 HTML 출력을 생성하려는 경우 (A) htmlString 메서드를 호출하여 각 객체에 대해 호출하거나 (B) 방문자 패턴을 사용하여 방문하는 각 노드에 대해 HTML 출력을 생성하는 방법을 알고있는 구체적인 방문자를 만듭니다.

이전 접근 방식은 더 일반적이며 작업 T의 논리는 클래스 X, Y 및 Z에 걸쳐 작은 덩어리로 분산되어 있습니다. 후자의 접근 방식은 모든 관련 코드를 단일 방문자 개체에 배치하므로 유지 관리를 단순화하고 "나는 그 하나의 수업을 잊어 버렸다 ..."라는 문제를 예방한다. 그러나 방문객 패턴은 단순한 상황에서는 다소 무거운 짐이 될 것입니다. 실제로는 여러 가지 다른 병렬 기능이 있고 기능이 수행되는 클래스에서 논리를 추상화하려는 경우에 효과적입니다. 예를 들어, PDF 또는 RTF 출력 등을 생성하는 다른 방문자를 구현할 수 있습니다. 각 방문자는 재귀를 처리하고 필요에 따라 자체 방문 메소드를 호출 할 수 있으며 별도의 방문자가 완전히 다른 순서를 사용할 수 있습니다.

많은 언어에서 방문자 패턴은 메서드 오버로드 (동일한 이름, 다른 서명/인수)를 사용한다는 점에 유의해야합니다. Objective-C는 메소드 오버로딩을 허용하지 않으므로 별개의 메소드 이름을 사용해야하지만, 실제로 어떤 오버로드가 호출되는지 알지 못하여 발생하는 버그를 피할 수 있습니다.

2

방문자 패턴을 구현하는 데 범주를 사용할 수 있습니다. 거기에 방문한 클래스 '공용 인터페이스의 더 오염이 없다하고 모든 일이 방문자 클래스의 컴파일 단위로 캡슐화 할 수

@protocol Visit 
- (void)acceptVisitor:(MyVisitor *)visitor; 
@end 

@interface Foo (Visit) <Visit> 
@end 

@interface Bar (Visit) <Visit> 
@end 

@implementation MyVisitor 

- (void)visit:(id)someObject { 
    if ([someObject conformsToProtocol:@protocol(Visit)]) { 
     [(id<Visit>)someObject acceptVisitor:self]; 
    } 
} 

- (void)visitFoo:(Foo *)foo { ... } 

- (void)visitBar:(Bar *)bar { ... } 

@end 

@implementation Foo (Visit) 
- (void)acceptVisitor:(MyVisitor *)visitor { 
    [visitor visitFoo:self]; 
} 
@end 

@implementation Bar (Visit) 
- (void)acceptVisitor:(MyVisitor *)visitor { 
    [visitor visitBar:Self]; 
} 
@end 

이, IMO 깔끔한 고전 GoF의 방문자 디자인보다.