代理设计模式的基本概念
代理是指一个对象提供机会会对另一个对象中行为发生变化时做出的反应。
总而言之,代理设计默认的基本思想----两个对象协同解决问题,通常运用于对象间通信。
代理设计模式的基本特点
- 简化了对象的行为,最大化减小对象之间的耦合度
- 使用代理,一般来说无需子类化
- 简化了我们应用程序的开发,既容易实现,而且灵活
下面我们使用租房子的一个小例子来模拟代理模式
(在其中:房子的主人为:真实角色RealSubject;中介为:代理角色Proxy;作为要去租房子的我们,
我们平时一般见不到房子的主人,此时我们去找中介,让中介直接和找房主交涉,把房子租下来,
直接跟租房子打交道的是中介。中介就是在租房子的过程中的代理者),看下结构图:
1:协议声明:
#import <Foundation/Foundation.h>
@protocol FindApartment <NSObject>
-(void)findApartment;
@end
2:代理角色声明(Agent.h)头文件声明
#import <Foundation/Foundation.h>
#import "FindApartment.h"
@interface Agent : NSObject <FindApartment>
@end
3:代理角色实现(Agent.m)实现文件
#import "Agent.h"
@implementation Agent
-(void)findApartment{
NSLog(@"findApartment");
}
@end
4:真实角色声明(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;
@end
5:真实角色实现(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];
}
@end
6:测试代理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;
}