我个人更喜欢把委托(Delegate)模式称为代理(Proxy)模式。还是那句话,第一次接触代理模式是在Java中接触的,在Java中实现代理模式和接口是少不了的。当时学习Spring的时候用到了接口回调,其实就是实现的委托代理模式。简单的说代理就是把相应的功能交给实现接口的相应的类中来解决。在OC中没有接口该如何实现代理呢?前面的博客中笔者说提了一句,在OC中的协议和Java中的接口极为相似,都是只声明方法而不去实现,方法的实现在OC中交个遵循协议的类,而在Java中方法的实现交给实现接口的类。其实学习一门新的语言和以前学习过的语言对比着理解还是蛮好理解的,废话少说,切入正题,谈一下OC中的委托代理模式。
下面还是用房屋中介和房东的例子来表示OC中的代理模式。包租公把房子委托给租房中介来出租,包租公每月收房租就ok啦~。
1.在Java中写代理的话,我会先写房屋中介的接口,所以在OC中我们首先也要先声明房屋中介的协议,Protocol中的方法是每个房屋中介必须有的方法,所以在Java中会抽象成接口,而在OC中我们会把他声明为协议,然后让每个方法声明为必须的,协议如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
// // RentHouse.h // Memory // // Created by ludashi on 14-8-7. // Copyright (c) 2014年 Mr.li. All rights reserved. // #import <Foundation/Foundation.h> @protocol RentHouse <NSObject> //在卖房子协议里定义两个必须的方法 @required //中介卖房子 - ( void )rentHouse; //把钱给用户 - ( void )payMoney; @end |
2.房屋中介的协议声明完我们先不用着急,声明中介类的,因为中介太多啦! 包租公要租房房子,客户就是上帝,所以我们先变包租公类, 包租公对中介公司的要求不高只要能给我把房子租出去,然后给钱就完事,所以只要遵守之前定义的房屋中介的协议即可,我们可以这样定义包租公:
interface代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
// Landlord.h // Memory // // Created by 鲁大师 on 14-8-7. // Copyright (c) 2014年 Mr.li. All rights reserved. // #import <Foundation/Foundation.h> //引入协议 #import "RentHouse.h" @interface Landlord : NSObject //房东的中介公司,符合买房子和付款都行 //agent是符合协议的对象传入都行 @property (assign) id<RentHouse> agent; //往外租房,委托给代理公司 -( void ) rentHouse; //包租婆收租啦 -( void ) receiveMoney; @end |
实现代码: 在实现代码中包租公会把房子通过协议中的saleHouse方法委托给租房中介
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
#import "Landlord.h" @implementation Landlord //往外租房,委托给代理公司 -( void ) rentHouse { NSLog(@ "我是包租公: ludashi, 我把房子租出去了!" ); //调用委托公司的卖房方法,委托关系调用 [self.agent rentHouse]; } //包租婆收租啦 -( void ) receiveMoney { NSLog(@ "ludashi: 每个月我包租公最高兴,因为又可以收租啦!" ); } @end |
3.包租公妥啦以后我们就开始找中介公司啦,中介公司首先得符合我们的协议(在java中就是要实现我们之前的接口),在中介公司中因为要和包租公建立合作关系所以用到了包租公的类,我们用@class来声明,目的减少模块之间的耦合性。
interface代码如下:
1
2
3
4
5
6
7
8
9
|
#import <Foundation/Foundation.h> //引入协议文件 #import"RentHouse.h" //为了解耦我们用@class声明房东类,代替引入房东的头文件 @ class Landlord; @interface HouseSaler : NSObject<RentHouse> //房东为中介的客户,所以定义一个客户对象 @property (assign) Landlord *customer; @end |
实现方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
#import "HouseSaler.h" #import "Landlord.h" @implementation HouseRent //实现卖房方法 -( void )RentHouse { NSLog(@ "agent: 租房了,我在有好多房子;" ); [self payMoney]; } //付钱给用户 -( void ) payMoney { NSLog(@ "agent:房子租出去啦!哎!得把钱给用户啊!!" ); [self.customer receiveMoney]; } @end |
4.测试:包租公要找中介公司
1
2
3
4
5
6
7
8
9
10
11
12
|
//委托模式的测试 //实例化包租公 Landlord *ludashi = [Landlord new ]; //实例化中介 HouseSaler *agent = [HouseRent new ]; //用户选择代理公司,这个公司只要遵守出租协议即可 ludashi.agent = agent; agent.customer = ludashi; //房东买房 [ludashi rentHouse]; |
运行结果:
1
2
3
4
|
2014-08-07 18:04:01.717 Memory[21273:303] 我是包租公: ludashi, 我把房子租出去了! 2014-08-07 18:04:01.719 Memory[21273:303] agent: 租房了,我在有好多房子; 2014-08-07 18:04:01.719 Memory[21273:303] agent:房子租出去啦!哎!得把钱给用户啊!! 2014-08-07 18:04:01.720 Memory[21273:303] ludashi: 每个月我包租公最高兴,因为又可以收租啦! |
上面测试时我们是通过代码直接把房屋出租公司和包租公进行合作关系的,更合理的做法是在租赁公司中加一个注册方法,方便用户和租赁公司形成委托关系,所以很有必要实现我们的register方法,在房屋租赁公司里加入注册方法,其他的不需要改变,代码如下:
1 //实现注册方法,把房东的对象传入中介 2 -(void)registerInfo:(Landlord *)vCustomer 3 { 4 //建立委托关联,产生委托关系 5 self.customer = vCustomer; 6 //包租公选择了一家符合协议的房屋出租公司 7 self.customer.agent = self; 8 }
那么我们进行测试的时候需要通过register方法来进行成立合作关系
测试时把代码
1 //用户选择代理公司,这个公司只要遵守出租协议即可 2 ludashi.agent = agent; 3 agent.customer = ludashi;
换成
//用户在房屋出租公司进行用户注册形成合作关系 [agent registerInfo:ludashi];
即可,其实本子上就是把上面的两行代码进行了一个封装,大概就是设计模式中的模板方法模式吧。到这的话委托代理模式就差不多了