代理設計模式的基本概念
代理是指一個對象提供機會會對另一個對象中行為發生變化時做出的反應。
總而言之,代理設計默認的基本思想----兩個對象協同解決問題,通常運用于對象間通信。
代理設計模式的基本特點
- 簡化了對象的行為,最大化減小對象之間的耦合度
- 使用代理,一般來說無需子類化
- 簡化了我們應用程序的開發,既容易實現,而且靈活
下面我們使用租房子的一個小例子來模擬代理模式
(在其中:房子的主人為:真實角色RealSubject;中介為:代理角色Proxy;作為要去租房子的我們,
我們平時一般見不到房子的主人,此時我們去找中介,讓中介直接和找房主交涉,把房子租下來,
直接跟租房子打交道的是中介。中介就是在租房子的過程中的代理者),看下結構圖:
1:協議聲明:
#import <Foundation/Foundation.h> @protocol FindApartment <NSObject> -(void)findApartment; @end2:代理角色聲明(Agent.h)頭文件聲明
#import <Foundation/Foundation.h> #import "FindApartment.h" @interface Agent : NSObject <FindApartment> @end3:代理角色實現(Agent.m)實現文件
#import "Agent.h" @implementation Agent -(void)findApartment{ NSLog(@"findApartment"); } @end4:真實角色聲明(Person.h)頭文件聲明
#import <Foundation/Foundation.h> #import "FindApartment.h" @interface Person : NSObject { @private NSString *_name; id<FindApartment> _delegate; //委托人(具備中介找房子的協議) } @property(nonatomic,copy) NSString *name; @property(nonatomic,assign)id<FindApartment> delegate; -(id)initWithName:(NSString *)name withDelegate:(id<FindApartment>) delegate; -(void)wantToFindApartment; @end5:真實角色實現(Person.m)實現
#import "Person.h" //定義私有方法 @interface Person() -(void)startFindApartment:(NSTimer *)timer; @end @implementation Person @synthesize name=_name; @synthesize delegate=_delegate; -(id)initWithName:(NSString *)name withDelegate:(id<FindApartment>) delegate{ self=[super init]; if(self){ self.name=name; self.delegate=delegate; } return self; } -(void)wantToFindApartment{ [NSTimer scheduledTimerWithTimeInterval:2 target:self selector:@selector(startFindApartment:) userInfo:@"Hello" repeats:YES]; } -(void)startFindApartment:(NSTimer *)timer{ //NSString *userInfo=[timer userInfo]; [self.delegate findApartment]; } @end6:測試代理main.m方法
#import <Foundation/Foundation.h> #import "Person.h" #import "Agent.h" int main(int argc, const char * argv[]) { @autoreleasepool { // insert code here... NSLog(@"Hello, World!"); Agent *agent=[[Agent alloc]init]; Person *jack=[[Person alloc]initWithName:@"jack" withDelegate:agent]; [jack wantToFindApartment]; [[NSRunLoop currentRunLoop]run]; [jack autorelease]; } return 0; }