Objective-Cのカテゴリ==ビジターパターン?
-
20-09-2019 - |
質問
あなたはObjective-Cのカテゴリはビジターデザインパターンでの実装されていると思いますか?
解決
いいえ、Objective-Cのカテゴリは、ビジターパターンの実装ではありません。サブクラスなしに、既存のクラスにメソッドを注入する手法はほとんどの言語では不可能であるため、カテゴリーは本当に、デザインパターンの世界で完全に一致していません。私はそれが Decoratorパターンのに近いかなと思うが、そのパターンは、通常、組成物を用いて実装される、すなわちオブジェクトのインスタンスをラップすることによって、あなたは「強化」したいと思います。
Visitorパターンは、たとえばなどのオブジェクト、構造体、さまざまなに適用することができるアルゴリズムのロジックをカプセル化するために有用であるあなたがオブジェクトのグラフのためのHTML出力を作成したい場合は、、、あなたは(A)htmlString
を書くことができ各オブジェクトのメソッドと、各オブジェクト、または(B)ビジターパターンを使用して、訪問ノードごとにHTML出力を生成する方法を知っている具体的な訪問者を作成するためにそれを呼び出します。
前者のアプローチはより一般的であり、タスクTのためのロジックはクラスXの両端の小さなチャンクで散乱され、YとZの後者のアプローチは、メンテナンスを簡素化し、防止する傾向がある単一ビジタ・オブジェクトに関連するすべてのコードを配置します問題「私は1つのクラスを...忘れてしまいました」。ただし、ビジターパターンは、ほぼ間違いなく、やや強引簡単な状況にある - それは本当に報わどこに複数の異なる並列機能を持っていると機能が実行されている上のクラスから抽象化ロジックしたいときです。たとえば、各訪問者は、再帰の世話をし、必要な順序で独自の訪問のメソッドを呼び出して、別の訪問者は完全に明確な順序を使用することができますすることができますなど、PDFまたはRTF出力を生成する他の訪問者を実装するかもしれません。
多くの言語では、ビジターパターンメソッドオーバーロード(同じ名前、異なる署名/引数)を使用することに留意すべきです。 Objective-Cのメソッドのオーバーロードを許可していないので、あなたは明確なメソッド名を使用する必要がありますが、これは実際に呼び出されているオーバーロードを知らないことによって発生するバグを防ぐことができます。
他のヒント
カテゴリーは、ビジターパターンを実装するために使用することができます。
@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
そこに訪れたクラスの公開インタフェースの無公害だんと全部がビジタークラスのコンパイル単位内でカプセル化することができるように、これは、古典的なGoFのビジターデザインよりもIMO滑らかな印象です。