訪問者模式(Visitor),表示一個作用於某對象結構中的各元素的操作。它使你可以在不改變各元素的類的前提下定義作用於這些元素的新操作。
訪問者模式類結構圖。
訪問者模式適用於數據結構相對穩定的系統,它把數據結構和作用於結構上的操作之間的耦合解脫開,使得操作結合可以相對自由地演化。
訪問者模式的目的是要把處理從數據結構分離出來。很多系統可以按照算法和數據結構分開,如果這樣的系統有比較穩定的數據結構,又有易於變化的算法的話,使用訪問者模式就是比較合適的,因爲訪問者模式使得算法操作的增加變得容易。
訪問者模式的優點就是增加新的操作很容易,因爲增加新的操作就意味着增加一個新的訪問者。訪問者模式將有關的行爲集中到一個訪問者對象中。
那其實,訪問者模式的缺點也就是使增加新的數據結構變得苦難了。所以,GoF四人中的一個作者增經說過,‘大多時候你並不需要訪問者模式,但當一旦你需要訪問者模式的時候,那就是真的需要它了’。
那麼下面還是老慣例,給大家展示一下簡單的實現(再次說明一下,這些代碼都使在ARC環境下編譯的!)。
-
Visitors類接口
1
2
3
4
5
6
7
|
#import
<Foundation/Foundation.h> @class
ConcreteElementA,ConcreteElementB; @interface
Visitors : NSObject -( void )VisitConcreteElementA:(ConcreteElementA
*)concreteElementA; -( void )VisitConcreteElementB:(ConcreteElementB
*)concreteElementB; @end |
-
Visitors類實現
1
2
3
4
5
6
7
8
9
10
11
12
|
#import
"Visitors.h" #import
"ConcreteElementA.h" #import
"ConcreteElementB.h" @implementation
Visitors -( void )VisitConcreteElementA:(ConcreteElementA
*)concreteElementA{ return ; } -( void )VisitConcreteElementB:(ConcreteElementB
*)concreteElementB{ return ; } @end |
-
ConcreteVisitor1類接口
1
2
3
4
|
#import
"Visitors.h" @interface
ConcreteVisitor1:Visitors @end |
-
ConcreteVisitor1類實現
1
2
3
4
5
6
7
8
9
10
|
#import
"ConcreteVisitor1.h" #import
"ConcreteElementA.h" @implementation
ConcreteVisitor1 -( void )VisitConcreteElementA:(ConcreteElementA
*)concreteElementA{ NSString
*eleName = NSStringFromClass ([concreteElementA
class ]); NSString
*visitorName = NSStringFromClass ([ self
class ]); NSLog (@ "%@被%@訪問" ,
eleName, visitorName); } @end |
-
ConcreteVisitor2類接口
1
2
3
4
|
#import
"Visitors.h" @interface
ConcreteVisitor2:Visitors @end |
-
ConcreteVisitor2類實現
1
2
3
4
5
6
7
8
9
10
|
#import
"ConcreteVisitor2.h" #import
"ConcreteElementB.h" @implementation
ConcreteVisitor2 -( void )VisitConcreteElementB:(ConcreteElementB
*)concreteElementB{ NSString
*eleName = NSStringFromClass ([concreteElementB
class ]); NSString
*visitorName = NSStringFromClass ([ self
class ]); NSLog (@ "%@被%@訪問" ,
eleName, visitorName); } @end |
-
Elements類接口
1
2
3
4
5
6
|
#import
<Foundation/Foundation.h> @class
Visitors; @interface
Elements : NSObject -( void )Accept:(Visitors*)visitor; @end |
-
Elements類實現
1
2
3
4
5
6
7
8
|
#import
"Elements.h" #import
"Visitors.h" @implementation
Elements -( void )Accept:(Visitors
*)visitor{ return ; } @end |
-
ConcreteElementA類接口
1
2
3
4
5
|
#import
"Elements.h" @interface
ConcreteElementA :Elements -( void )OperationA; @end |
-
ConcreteElementA類實現
1
2
3
4
5
6
7
8
9
10
11
|
#import
"ConcreteElementA.h" #import
"Visitors.h" @implementation
ConcreteElementA -( void )OperationA{ return ; } -( void )Accept:(Visitors
*)visitor{ [visitor
VisitConcreteElementA: self ]; } @end |
-
ConcreteElementB類接口
1
2
3
4
5
|
#import
"Elements.h" @interface
ConcreteElementB :Elements -( void )OperationB; @end |
-
ConcreteElementB類實現
1
2
3
4
5
6
7
8
9
10
11
|
#import
"ConcreteElementB.h" #import
"Visitors.h" @implementation
ConcreteElementB -( void )OperationB{ return ; } -( void )Accept:(Visitors
*)visitor{ [visitor
VisitConcreteElementB: self ]; } @end |
-
ObjectStructure類接口
1
2
3
4
5
6
7
8
9
10
11
|
#import
<Foundation/Foundation.h> @class
Elements; @class
Visitors; @interface
ObjectStructure : NSObject { NSMutableArray
*elements; } -( void )Attach:(Elements*)element; -( void )Detach:(Elements*)element; -( void )Accept:(Visitors*)visitor; @end |
-
ObjectStructure類實現
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
#import
"ObjectStructure.h" #import
"Elements.h" @implementation
ObjectStructure -( id )init{ if
( self
== [ super
init]) { elements
= [[ NSMutableArray
alloc]init]; } return
self ; } -( void )Attach:(Elements
*)element{ [elements
addObject:element]; } -( void )Detach:(Elements
*)element{ [elements
removeObject:element]; } -( void )Accept:(Visitors
*)visitor{ for (Elements
*e in elements) { [e
Accept:visitor]; } } @end |
-
Main方法調用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
#import
<Foundation/Foundation.h> #import
"ObjectStructure.h" #import
"ConcreteElementA.h" #import
"ConcreteElementB.h" #import
"ConcreteVisitor1.h" #import
"ConcreteVisitor2.h" int
main ( int
argc, const
char
* argv[]) { @autoreleasepool { ObjectStructure
*o = [[ObjectStructure alloc]init]; ConcreteElementA
*eA = [ConcreteElementA new ]; ConcreteElementB
*eB = [ConcreteElementB new ]; [o
Attach:eA]; [o
Attach:eB]; ConcreteVisitor1
*v1 = [ConcreteVisitor1 new ]; ConcreteVisitor2
*v2 = [ConcreteVisitor2 new ]; [o
Accept: v1]; [o
Accept: v2]; } return
0; } |