2009-08-26 10 views

Antwort

11

Nein, Objective-C-Kategorien sind keine Implementierung des Besuchermusters. Kategorien haben in der Entwurfsmusterwelt nicht wirklich eine genaue Übereinstimmung, da die Technik des Injizierens von Methoden in bestehende Klassen ohne Unterklassen in den meisten Sprachen nicht möglich ist. Ich würde sagen, es ist näher an der decorator pattern, aber dieses Muster wird in der Regel mit Komposition implementiert, d. H. Durch Umhüllen einer Instanz des Objekts, das Sie "erweitern" möchten. Das Besuchermuster ist nützlich für das Verkapseln von Algorithmuslogik, die auf eine Vielzahl von Objekten, Strukturen usw. angewendet werden kann. Wenn Sie beispielsweise eine HTML-Ausgabe für ein Objektdiagramm erstellen möchten, könnten Sie (a) schreiben: a htmlString Methode für jedes Objekt und rufen Sie es für jedes Objekt auf oder (B) verwenden Sie das Besuchermuster und erstellen Sie einen konkreten Besucher, der weiß, wie er für jeden von ihm besuchten Knoten eine HTML-Ausgabe erstellt.

Der erste Ansatz ist generischer, und die Logik für Task T ist in kleinen Blöcken über die Klassen X, Y und Z verstreut. Der letztere Ansatz platziert den gesamten Code in einem einzelnen Besucherobjekt, was die Wartung vereinfacht und vereinfacht Verhindere das Problem "Ich habe diese Klasse vergessen". Allerdings ist das Besuchermuster für einfache Situationen wohl etwas schwerfällig - wo es sich wirklich lohnt, wenn Sie mehrere verschiedene parallele Funktionalitäten haben und die Logik von den Klassen abstrahieren möchten, auf denen die Funktionalität ausgeführt wird. Sie können beispielsweise andere Besucher implementieren, die PDF- oder RTF-Ausgaben usw. erzeugen. Jeder Besucher kann Rekursionen durchführen und seine eigenen Besuchsmethoden in der erforderlichen Reihenfolge aufrufen, und separate Besucher können eine völlig unterschiedliche Reihenfolge verwenden.

Es sollte beachtet werden, dass das Besuchermuster in vielen Sprachen die Methodenüberladung verwendet (gleicher Name, unterschiedliche Signatur/Argumente). Da Objective-C das Überladen von Methoden nicht zulässt, müssen Sie eindeutige Methodennamen verwenden. Dies kann jedoch dazu beitragen, Fehler zu vermeiden, die dadurch entstehen, dass Sie nicht wissen, welche Überladung aufgerufen wird.

2

Kategorien können verwendet werden, um das Besuchermuster zu implementieren.

@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 

Dies ist IMO ordentlicheres als die Design-Klassiker GoF Besucher, da es öffentliche Schnittstellen keine Verschmutzung der besuchten Klassen ist und das Ganze kann in der Besucherklasse Übersetzungseinheit verkapselt werden.

Verwandte Themen