您的位置:首页 > 其它

设计模式之代理设计模式

2015-08-05 18:10 295 查看


<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流!

代理设计模式
什么是设计模式?
百度百科上给出的答案是:设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。
而我的答案是:设计框架的方案,一个好的设计模式,可以让架构变得非常的好。

代理模式和观察者模式,他们两个在代码实现上面非常的像,但是他们的思想不一样。

那么什么是代理呢?
苹果官方给出的答案是:代理是一种简单而功能强大的设计模式,这种模式用于一个对象“代表”另外一个对象和程序中其他的对象进行交互。
主对象(这里指的是delegating object)中维护一个代理(delegate)的引用并且在合适的时候向这个代理发送消息。这个消息通知“代理”主对象即将处理或是已经处理完了某一个事件。这个代理可以通过更新自己或是其它对象的UI界面或是其它状态来响应主对象所发送过来的这个事件的消息。或是在某些情况下能返回一个值来影响其它即将发生的事件该如何来处理。代理的主要价值是它可以让你容易的定制各种对象的行为。注意这里的代理是个名词,它本身是一个对象,这个对象是专门代表被代理对象来和程序中其他对象打交道的。

下面有一个情景,有一个人要去看电影,但是他没有时间去买电影票,因此他找了他的朋友,要他帮忙咨询电影票的信息。然后由他的朋友告诉他,有哪些上映的电影和电影票的价格,这个就是典型的代理模式。

常用的解决方案:
定义一个代理(Agent)类
Agent.h文件
//Agent.h
#import <Foundation/Foundation.h>
@interface Agent : NSObject

- (double) ticketPrice;
- (int) leftTicketNumber;

@end


Agent.m文件

//Agent.m
@implementation Agent

- (double) ticketPrice
{
return 100;
}
- (int) leftTicketNumber
{
return 10;
}

@end


然后再定义一个Person类,里面有代理(Agent)这个属性
Person.h文件

//Person.h
#import <Foundation/Foundation.h>
#import <Agent.h>
@interface Person : NSObject

- (void) buyTicket;
//拥有一个代理属性
@property (nonatomic, retain) Agent *delegate;

@end


Person.m文件

//Person.m
#import "Person.h"

@implementation Person

- (void) buyTicket
{
double price = [_delegate ticketPrice];
int number = [_delegate leftTicketsNumber];
NSLog("@通过代理的帮忙,票价 = %d,还剩%d张票",price,number);
}

- (void)dealloc
{
[_delegate release];
[super dealloc];
}

@end


最后,在main函数中,创建一个人的对象,然后给人对象里面的Agent属性赋值,然后就可以调用buyTicket方法了。

//main.m
#import <Foundation/Foundation>
#import "Person.h"
#import "Agent.h"

int main(int argc, const char * argv[])
{
@autoreleasepool {
//人
Person *p = [ [Person alloc] init];
//代理
Agent *a = [ [Agent alloc] init];
//设置人的代理属性
p.delegate = a;
//人打算买电影票
[p buyTicket];
[a release];
[p release];
}
return 0;
}


这里,虽然体现了代理的思想,但是这个代理模式非常有问题,耦合性太强了。人这个类离开了代理这个类,就不能完成此功能。所以上面的代码扩展性不强。

如果我们要扩展的话,首先Person类中的代理属性的类型不能写死。然后将代理里面的方法全部都放到某个协议里面去,那么我们要代理跟我们做事的时候,就只要告诉他,遵守这个代理就可以拥有代理里面的所有方法了。

如:@property (nonatomic, retain) Agent *delegate;

改写成:@property (nonatomic, retain) id<TicketDelegate> delegate;

修改后:
创建一个协议,然后将要完成的功能声明在协议中,哪个代理遵守了这个协议,那么它只要实现里面的方法就可以了。也就是说,即便是跟换很多的代理,只要遵守协议就行。

创建一个TicketDelegate协议
//TicketDelegate.h
#import <Foundation/Foundation.h>
@protocol TicketDelegate <NSObject>
- (double) ticketPrice;
- (int) leftTicketNumber;
@end


创建一个代理Agent类
Agent.h文件
//Agent.h
#import <Foundation/Foundation.h>
@interface Agent : NSObject <TicketDelegate>

@end


Agent.m文件
//Agent.m
@implementation Agent
- (double) ticketPrice
{
return 100;
}
- (int) leftTicketNumber
{
return 10;
}
@end


创建一个人类(Person)
Person.h文件
//Person.h
#import <Foundation/Foundation.h>
#import <TicketDelegate.h>
#import <Agent.h>
@interface Person : NSObject

- (void) buyTicket;
//拥有一个代理属性
@property (nonatomic, retain) id<TicketDelegate> delegate;

@end


Person.m文件
//Person.m
#import "Person.h"

@implementation Person

- (void) buyTicket
{
double price = [_delegate ticketPrice];
int number = [_delegate leftTicketsNumber];
NSLog("@通过代理的帮忙,票价 = %d,还剩%d张票",price,number);
}

- (void)dealloc
{
[_delegate release];
[super dealloc];
}

@end


main函数中
#import <Foundation/Foundation>
#import "Person.h"
#import "Agent.h"

int main(int argc, const char * argv[])
{
@autoreleasepool {
//人
Person *p = [ [Person alloc] init];
//代理
Agent *a = [ [Agent alloc] init];
//设置人的代理属性
p.delegate = a;
//人打算买电影票
[p buyTicket];
[a release];
[p release];
}
return 0;
}
此时,Agent就是Person的代理了。其扩展性也增强了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  代理模式