【コラム】
23種類のデザインパターンを取り上げるこの連載も、いよいよ最後のパターンとなった。Visitorパターンである。最後となる「訪問者」を紹介しよう。
ある構造を持つオブジェクトの集合があり、そのそれぞれのオブジェクトに対して処理を行う事を考えてみよう。たとえば、木構造である。木構造では、ノードと呼ばれるオブジェクトが、樹形図を構成している。ここに含まれるオブジェクトを走査し、ノードの種類に応じて処理を行っていくものだ。こういったプログラミングには、構文木を解析するコンパイラや、HTMLのDOMツリーに対する処理などがあるだろう。
このとき、処理を行うのはどのオブジェクトにすべきであろうか。一つの考え方は、ノードオブジェクトに行わせるというものである。自分自身で処理を行う訳だから、筋は通っているだろう。だがこの方法だと、ノードという木構造を表す機能と、コンパイルといった特定の処理が、同一のクラスになってしまう。クラスの再利用性を考えると、構造を表すクラスと、処理を行うクラスは切り離しておきたい。
そこで、オブジェクトの走査を行うときに、それぞれのオブジェクトを訪れて処理を行う「訪問者」となるクラスを作ろう。これがVisitorパターンの考え方だ。Visitorパターンを使うときは、走査を行いながらそれぞれのオブジェクトにVisitorを訪問させてやる。このVisitorの中で、処理を行うのだ。
Visitorパターンに登場するクラスを紹介しよう。まず、処理を行う対象となるクラスがある。これをElementクラスとしよう。そして、Elementクラスに対して処理を行うクラスを、Visitorクラスとする。
また、Elementの集合を管理する、構造を定義するものもあるだろう。これは、Object Structureと呼ぼう。たとえばObject Strctureの実装として、Iteratorパターンを適用するという事も考えられるだろう。
これらを図示すると、次のようになる。
ここで、VisitorとElementの間に参照関係がないことに注意してほしい。Object Structureの中からElementを走査してVisitorを適用させるのは、ClientまたはObject Structureの仕事になる。
では、Objective-CでのVisitorパターンの実装を紹介しよう。
まず、Elementクラスを定義する。Elementクラスには、Visitorを適用させるためのメソッドが必要だ。これを、accept:としよう。具体的なサブクラスとして、ElementAとElementBを定義しておく。
List 1.
@interface Element : NSObject
{
}
// Visitorクラスの訪問を受け付ける
- (void)accept:(Visitor*)visitor;
@end
@interface ElementA : Element
{
}
@end
@interface ElementB : Element
{
}
@end
Elementクラスの実装の前に、Visitorクラスを定義しよう。Visitorクラスには、Elementを処理するためのメソッドを定義する。これを、visitElementA:、visitElementBとしよう。
@interface Visitor : NSObject
{
}
- (void)visitElementA:(ElementA*)element;
- (void)visitElementB:(ElementB*)element;
@end
このvisitElementA:とvisitElementB:を、Elementクラスが呼び出すことになるのだ。
では、Elementクラスの実装を行おう。Elementクラスに定義されているaccept:メソッドの中で、VisitorクラスのvisitElementA:またはvisitElementB:を呼び出すのだ。ElementAとElementBとで、それぞれaccept:をオーバーライドすることで実現しよう。
@implementation ElementA
- (void)accept:(Visitor*)visitor
{
// Visitorクラスに訪問させる
[visitor visitElementA:self];
}
@end
@implementation ElementB
- (void)accept:(Visitor*)visitor
{
// Visitorクラスに訪問させる
[visitor visitElementB:self];
}
@end
これで、VisitorクラスがElementを処理出来るようになる。VisitorクラスのvisitElementA:、およびvisitElementB:では、それぞれのElementの種類に応じて処理を行うことになる。
これがVisitorパターンの実装となる。次回は、CocoaフレームワークでのVisitorパターンを実現している例を紹介しよう。
| 理研、脳・脊髄形成に必要な神経板湾曲の仕組みを解明 [20:16 5/25] |
| 京大、「慢性閉塞性肺疾患」患者の労作時呼吸困難は鍼治療が有効と実証 [20:08 5/25] |
| 120Hz SHVカメラ用イメージセンサーを使った撮像装置 - SHVフルスペック化へ [18:10 5/25] |
| 京大、視覚による物体認知は前頭前野からのトップダウン信号が重要と確認 [17:45 5/25] |
| 製品数の拡大だけでなくBCPの展開なども含めた総合力で事業の強化を図るTI [17:25 5/25] |
|
[9nine]制服姿見納め? セーラー服で登場も川島海荷「4人はコスプレ」 [19:15 5/27] エンタメ |
|
「NO.6」4巻は書き下ろしドラマCD付、木乃のサイン会も [18:49 5/27] ホビー |
|
[今週の新刊]マンガ大賞3回ノミネート「アイアムアヒーロー」 カープ愛「球場ラヴァーズ」も [18:33 5/27] ホビー |
|
「ゆりてつ」サイン会は作者と都電に揺られるツアー仕立て [17:45 5/27] ホビー |
|
【ネタバレもありの徹底解明コラム】『サザエさん』タマの意外な事実 [17:30 5/27] ホビー |
4つの診断で、自分の適性を見つめなおそう!
働くこと・挑戦し続けることへの思いを綴ったインタビュー
あなたにピッタリのアドバイスを読むことができます。
転職に必要な情報が収集できます
企業からアプローチのメッセージが届きます。