Objective-Cにおける”あり得ない”Visitorパターン実装

Visitorパターンてのがあります。
AcceptorをVisitorが渡り歩きますが、Acceptorもちょっと手助けする必要があります。
Acceptorを変更することなしに、Visitorを追加出来るという特徴があります。
Objective-Cにはカテゴリがありますので、Acceptorの手助けはカテゴリで追加することが出来てさらに便利です。

それでもAcceptorに色々追加するのは嫌なので、

@implementation NSObject(Acceptor)
- (void)accept:(id)visitor
{
	[visitor visit:self];
}
@end

だけで終わらせたい。
しかし、Objective-Cにはオーバーロードがない。
そういう場合はAcceptorごとにメソッドを追加することになります。

@implementation ClassA (Acceptor)
- (void)accept:(id)visitor
{
	[visitor visitClassA:self];
}
@end
@implementation ClassB (Acceptor)
- (void)accept:(id)visitor
{
	[visitor visitClassB:self];
}
@end

美しくありません!
それに、Visitorパターンの特徴は
Acceptorを変更することなしに、Visitorを追加出来る
であったはずです。これでは魅力半減です。*1


で、編み出したのがこれ。

@implementation NSObject(Acceptor)
- (void)accept:(id)visitor
{
	[visitor visit:self];
}
@end
@implementation NSObject(Visitor)
- (void)visit:(id)acceptor
{
	NSString *className = NSStringFromClass([acceptor class]);
	NSString *selName = [NSString stringWithFormat:@"visit%@:", className];
	SEL selector = NSSelectorFromString(selName);
	return [self performSelector:selector withObject:acceptor];
}
@end
@implementation Visitor
- (void)visitClassA:(id)acceptor
{
	// do something.
}

- (void)visitClassB:(id)acceptor
{
	// do something.
}
@end


すばらしい!
AcceptorはシンプルなままAcceptorごとに違ったメソッドが呼ばれてる!
Visitor側には多数のメソッドが必要ですが、これはオーバーロードを使っても同じこと。
完璧である!



クラスクラスタのことを考えなければ(w
あと速度。

*1:主観が大いに混ざっています。本来の特徴はそこではありません。