0113——代理模式

什么是代理?

  苹果的官方文档给了很清晰的解释:

  Delegation is a simple and powerful pattern in which one object in a program acts on behalf of, or in coordination with, another object. The delegating object keeps a reference to the other object—the delegate—and at the appropriate time sends a message to it. The message informs the delegate of an event that the delegating object is about to handle or has just handled. The delegate may respond to the message by updating the appearance or state of itself or other objects in the application, and in some cases it can return a value that affects how an impending event is handled. The main value of delegation is that it allows you to easily customize the behavior of several objects in one central object.

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

  Protocol(协议)只能定义公用的一套接口,但不能提供具体的实现方法。也就是说,它只告诉你要做什么,但具体怎么做,它不关心。

  当 一个类要使用某一个Protocol(协议)时,都必须要遵守协议。比如有些必要实现的方法,你没有去实现,那么编译器就会报警告,来提醒你没有遵守×× 协议。注意,我这里说的是警告,而不是错误。对的,就算你不实现那些“必要实现”的方法,程序也是能运行的,只不过多了些警告。

Protocol(协议)的作用:

1. 定义一套公用的接口(Public)

  • @required:必须实现的方法
  • @optional:可选 实现的方法(可以全部都不实现)

2. 委托代理(Delegate)传值:

它本身是一个设计模式,它的意思是委托别人去做某事。

比如:两个类之间的传值,类A调用类B的方法,类B在执行过程中遇到问题通知类A,这时候我们需要用到代理(Delegate)。

又比如:控制器(Controller)与控制器(Controller)之间的传值,从C1跳转到C2,再从C2返回到C1时需要通知C1更新UI或者是做其它的事情,这时候我们就用到了代理(Delegate)传值。

一、定义一套公用的接口(Public)

首先新建一个协议文件:

填上协议文件名及文件类型(选择Protocol):

ProtocolDelegate.h代码(协议不会生成.m文件):

#import @protocol ProtocolDelegate // 必须实现的方法
@required
- (void)error;

// 可选实现的方法
@optional
- (void)other;
- (void)other2;
- (void)other3;

@end

在需要使用到协议的类,import它的头文件:

#import "ViewController.h"
#import "ProtocolDelegate.h"

我这里选择的是入口文件

记得要遵守协议:

@interface ViewController () @end

这时会报一个警告,因为定义的协议里有一个是必须实现的方法,而我们没有去实现:

实现了必须实现的方法后,编译器就不会报警告了:

至于其它的可选方法,你可以选择实现,也可以全都不实现。

二、委托代理(Delegate)传值

在Storyboard上,先搭好界面,如下图:

新建ControllerB:

把B界面的类设置为ViewControllerB:

下面放出主要类文件代码,我在里面写了注释,大家应该能看懂。不懂也没有关系,我会在本文结尾放上Demo下载地址。

ViewController.m文件:

 1 #import "ViewController.h"
 2 #import "ProtocolDelegate.h"
 3 #import "ViewControllerB.h"
 4 @interface ViewController () @end
 5 @implementation ViewController
 6 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
 7 {
 8   ViewControllerB *vc = segue.destinationViewController;
 9   [vc setDelegate:self];
10 }
11 // 这里实现B控制器的协议方法
12 - (void)sendValue:(NSString *)value
13 {
14   UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"成功" message:value delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
15   [alertView show];
16 }
17 - (void)error
18 {
19 }
20 @end

ViewControllerB.h文件:

 1 #import // 新建一个协议,协议的名字一般是由“类名+Delegate”
 2 @protocol ViewControllerBDelegate // 代理传值方法
 3 - (void)sendValue:(NSString *)value;
 4
 5 @end
 6
 7 @interface ViewControllerB : UIViewController
 8
 9 // 委托代理人,代理一般需使用弱引用(weak)
10 @property (weak, nonatomic) id delegate;
11
12 @end

ViewControllerB.m文件:

 1 #import "ViewControllerB.h"
 2 @interface ViewControllerB ()
 3 @property (strong, nonatomic) IBOutlet UITextField *textField;
 4 @end
 5 @implementation ViewControllerB
 6 - (IBAction)backAction:(id)sender
 7 {
 8   if ([_delegate respondsToSelector:@selector(sendValue:)]) { // 如果协议响应了sendValue:方法
 9     [_delegate sendValue:_textField.text]; // 通知执行协议方法
10   }
11   [self.navigationController popViewControllerAnimated:YES];
12 }
13 @end

完成效果截图:

小结:

当你需要定义一套公用的接口,实现方法可以是不同的时候,你可以使用Protocol协议。

当你需要进行类与类之间的传值时,你也可以基于Protocol协议,使用代理设计模式进行传值。

时间: 2024-08-05 16:27:32

0113——代理模式的相关文章

Spring框架_代理模式(静态代理,动态代理,cglib代理)

共性问题: 1. 服务器启动报错,什么原因? * jar包缺少.jar包冲突 1) 先检查项目中是否缺少jar包引用 2) 服务器: 检查jar包有没有发布到服务器下:                                      用户库jar包,需要手动发布到tomcat. (每次新建项目) 3) 重新发布项目 * 配置文件错误 (web.xml / struts.xml /bean.xml /hibernate.xml / *.hbm.xml) 明确的提示 * 端口占用 * we

拦截器的设计思想——代理模式

代理模式:静态代理和动态代理 1.代理类和被代理类必须实现同一个借口 2.代理类和别代理类有一种关联关系 静态代理: 例如实现一个日志: //定义一个接口 public interface UserDao{ public void delete(); } //定义一个实现类 public class UserDaoImpl implements UserDao{ public void delete(){ System.out.pritln("成功删除"); } } //定义一个代理类

Java设计模式——代理模式

前言: 上一篇说到了策略模式.单类图上来说,它和本篇要说的代理模式还真是有些像似.都需要一个公共的接口,还有一些实现类.代理类(包装类)封装了一个接口对象,提供客户端调用.这些都很类似.不过,有一个细节需要我们注意一下,那就是这里的代理类也需要去继承这里的公共接口.而在策略模式中,包装类则不需要这么做. 概述: 代理模式就是定义一个原对象的代理对象,来帮助原对象和系统之外的业务作沟通.也就是说,如果我们不能直接或是不愿直接去使用原对象,那么我们就可以使用创建一个原对象的代理来进行操作. 本文链接

代理模式(Proxy)

代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问. 在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用. 代理模式一般涉及到的角色有 抽象角色:声明真实对象和代理对象的共工接口 代理角色:代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象.同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装. 真实角色:代理角色所代表的真实对

深刻理解代理模式在java中如何优化系统性能

最近参与实习公司的项目迭代,项目中需要实现系统的快速响应和大量数据处理.在不断的学习中获得一点儿心得,先记录下来.慢慢的修改! 关于代理模式的知识和简单应用之前的学习笔记中已经有记录了,可以复习一下.这里主要记录如何使用代理模式来实现延迟加载,进而提升系统系能和反应速度. 使用代理模式实现延迟加载的一个简单实例: 需求:项目中对系统的启动速度做了一定的要求 我们在系统首次加载时,因为不需要实际的数据来构造显示界面,这就为我们实现系统首次加载的快速响应提供了可能.在常规模式下,我们一般会在系统启动

使用反射机制调用属性和私有成员与代理模式的介绍

使用反射机制调用属性: 通过反射机制可以获得类的属性,获得到的属性同样的可以进行赋值.得值操作,调用getField方法并传递属性的名称可以获得[学Java,到凯哥学堂kaige123.com]指定的属性,调用getFields方法则可以获得全部属性,但是这种方式不能获得私有属性: 代码示例: Student类示例: 运行结果: 从运行结果可以看出只拿出了公开的属性,私有的属性拿不到. 使用反射机制调用私有成员: 1.调用私有属性 在反射机制里调用私有属性需要通过getDeclaredField

动态代理模式

动态代理模式简介: 动态代理能够自动监听代理对象的方法,并且能够自动生成代理类的代码,这样就不需要我们自己去重写代理对象里的方法了,这样解决了代理类代码因业务庞大而庞大的问题,因为动态代理模式会在代码运行时根据代码来在内存中动态生成一个代理类自动重写代理对象[学Java,到凯哥学堂kaige123.com]的方法,然后这个动态代理类再调用处理类里的代码,处理类再调用到实际方法上去.而且我们可以选择性的监听代理对象的方法,有些不需监听的方法就可以在处理类中过滤掉.所以动态代理的优势就在于可以自动的

设计模式(十四):代理模式

一.概述 代理模式为另一个对象提供一个替身或占位符以控制对这个对象的访问.其实就是代理就是做到类似转发的功能,针对不同代理,转发的具体实现不同. 二.解决问题 从原理知道他就是控制客户对一个对象的访问,它跟现实中的中介代理类似,只是作为代表做一些受理工作,真正执行的并不是它自己.比如买火车票,外面有很多火车票代理点,我们直接去代理点买票就好而不用跑到火车票买了(暂时不考虑网购哈). 三.结构类图 四.应用实例 在这个例子中,主要讲解远程代理,它可以作为另一个JVM上的本地代表.客户端调用代理的方

设计模式之代理模式

代理模式(Proxy)为其他对象提供一种代理以控制对这个对象的访问.使用场合,第一,远程代理,也就是为一个对象在不同的地址空间提供局部代表.这样可以隐藏一个对象存在于不同地址空间的事实:第二,虚拟代理,是根据需要创建开销很大的对象.通过它来存在实例化需要很长时间的真实对象:第三,安全代理,用来控制真实对象访问时的权限:第四,智能指引,是指当调用真实的对象时,代理处理另外一些事情.代理模式与外观模式有点像,但外观模式中外观与实体不一定具备相同的接口,两者都在一定程度上隐藏了系统的复杂性. 代理模式