Objective-C中的委托(代理)模式

        我个人更喜欢把委托(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];

  即可,其实本子上就是把上面的两行代码进行了一个封装,大概就是设计模式中的模板方法模式吧。到这的话委托代理模式就差不多了

上面的总结暂且这么说吧,是根据笔者自己的理解所总结的内容,不免有偏颇之处,欢迎批评指正,转载请注明出处。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏人人都是极客

Linux内核内存管理算法Buddy和Slab

有了前两节的学习相信读者已经知道CPU所有的操作都是建立在虚拟地址上处理(这里的虚拟地址分为内核态虚拟地址和用户态虚拟地址),CPU看到的内存管理都是对page...

5596
来自专栏java一日一条

优秀的Java程序测试是什么样的?

测试的名字至关重要,特别是从文档角度来看的话。我们应该能够大声读出测试的名字就像一组需求一样。事实上,有一个伟大的IntelliJ插件,叫Enso,它会将你的测...

662
来自专栏技术与生活

设计模式-命令模式

Client:确定具体的命令和接受者; Command:抽象命令接口,一般是接口类或者抽象类 ConcreteCommand:具体的命令执行,调用接受者 Inv...

1285
来自专栏架构之路

追源索骥:透过源码看懂Flink核心框架的执行流程

写在最前:因为这篇博客太长,所以我把它转成了带书签的pdf格式,看起来更方便一点。想要的童鞋可以到我的公众号“老白讲互联网”后台留言flink即可获取。

2.7K4
来自专栏图像识别与深度学习

蓝牙项目开发流程

70410
来自专栏Java帮帮-微信公众号-技术文章全总结

面试复习大纲(最全面)

Java基础 1.数组中的排序问题(笔试或者机试,前者可能性更大) 2.面向对象的理解 面向对象主要有四个特性: 封装、抽象、继承和多态。 封装:在面向对象语言...

3545
来自专栏java一日一条

优秀的Java程序测试是什么样的?

作为测试驱动设计和开发的忠实粉丝,我相信创造良好的测试是我们作为Java开发人员可以做的最重要的事情之一。我们写测试出于许多原因:

891
来自专栏Java帮帮-微信公众号-技术文章全总结

solr使用教程二【面试+工作】

6.3高亮显示 我们经常使用搜索引擎,比如在baidu 搜索 java ,会出现如下结果,结果中与关键字匹配的地方是红色显示与其他内容区别开来。 solr 默认...

4697
来自专栏杨建荣的学习笔记

初识YAML

晚上本来想看看Julia语言的,最后发现需要花额外的不少时间,就先放放,那就看看Yaml吧,要学习的话,周期短,本身也比较简单清晰。 早些年的...

2847
来自专栏FreeBuf

如何破解12位+字符的高强度密码?

看到这个标题,你肯定抱着怀疑的态度。破解 12+ 字符的密码,在理论上这是不可能的。因为按照安全专家的说法,想要破解一个 12+ 字符的高强度密码,大概需要 1...

3505

扫码关注云+社区

领取腾讯云代金券