代理模式, 委托模式
意图:为其他对象提供一种代理以控制对这个对象的访问。
访问控制,而非加强功能。
代理:指具有与代理元(被代理的对象)具有相同接口的类,客户端必须通过代理与被代理的目标类交互,而代理一般在交互过程中(交互前后),进行某些特别的处理。
代理模式.jpg角色和职责
-
Subject(抽象主题角色)
真实主题与代理主题的共同接口 -
RealSubject(真实主题角色)
定义了代理角色所代表的真实对象 -
Proxy(代理主题角色)
含有对真实主题角色的引用,代理角色通常在将客户端调用传递给真实的主题对象之前或者之后执行某些操作,而不是单纯返回真实的对象。
适用(场景)
为其他对象提供一种代理以控制对这个对象的访问。
提示:a中包含b类;a、b类实现协议类protocol
代码示例
#import <Foundation/Foundation.h>
@interface BuyerA : NSObject
- (void)buyTicket;
@end
@implementation BuyerA
- (void)buyTicket {
NSLog(@"BuyerA 买票");
}
@end
@interface BuyerB : NSObject
- (void)buyTicket;
@end
@implementation BuyerB
- (void)buyTicket {
NSLog(@"BuyerB 买票");
}
@end
@protocol Buyer <NSObject>
- (void)buyTicket;
@end
//遵守了协议 就可以做Person的代理帮他买票了
@interface BuyerC : NSObject<Buyer>
@end
@implementation BuyerC
- (void)buyTicket {
NSLog(@"遵守买票的协议 买票");
}
@end
@interface Person : NSObject
//关联A,让A帮忙买票
@property (nonatomic, strong) BuyerA *buyerA;
//或关联B,让B帮忙买票
@property (nonatomic, strong) BuyerB *buyerB;
//再换的话。。。所以用协议,不用关联具体的类型对象
@property (nonatomic, strong) id<Buyer> delegate;
- (void)buyTicket;
@end
@implementation Person
- (void)buyTicket {
NSLog(@"人自己 买票");
}
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
Person *p1 = [[Person alloc] init];
[p1 buyTicket];
//人 自己买票
BuyerA *a = [[BuyerA alloc] init];
p1.buyerA = a;
[p1.buyerA buyTicket];
//让A替自己买票
BuyerB *b = [[BuyerB alloc] init];
p1.buyerB = b;
[p1.buyerB buyTicket];
//让B替自己买票
BuyerC *c = [[BuyerC alloc] init];
p1.delegate = c; //只要是遵守了Buyer协议的都可以赋值
[p1.delegate buyTicket];
//让遵守协议的对象替自己买票
}
return 0;
/*
人自己 买票
BuyerA 买票
BuyerB 买票
遵守买票的协议 买票
*/
}
上述代码是代理模式思想的阐述:一个客户类不想或者不能直接引用一个委托对象,而代理类对象可以在客户类和委托对象之间起到中介的作用,其特征是代理类和委托类实现相同的接口.
iOS中的代理模式相对简单,没有动态代理(Dynamic Proxy:Java反射语法,不事先为每个原始类编写代理类,运行时动态创建原始类对应的代理类,然后再系统中用代理类替换掉原始类),没有远程代理、虚代理、保护代理、智能指引之分。以@protocol形式体现,传递方式是一对一,常用的是界面反向传值。
反向传值部分示例代码
ViewController.m主要代码
#import "ViewController.h"
#import "SubViewController.h"
@interface ViewController ()<SubVCDelegate>
@end
@implementation ViewController
- (IBAction)pushAction:(id)sender {
SubViewController *subVC = [[SubViewController alloc] init];
subVC.delegate = self;
[self.navigationController pushViewController:subVC animated:YES];
}
- (void)subVC:(SubViewController *)vc AndValue:(NSString *)value {
NSLog(@"VC---%@:%@", vc, value);
}
SubViewController.h主要代码
#import <UIKit/UIKit.h>
@class SubViewController;
@protocol SubVCDelegate <NSObject>
//默认@required
- (void)subVC:(SubViewController *)vc AndValue:(NSString *)value;
@end
@interface SubViewController : UIViewController
//weak规避循环引用
@property (nonatomic, weak) id<SubVCDelegate> delegate;
@end
SubViewController.h主要代码
#import "SubViewController.h"
@interface SubViewController ()
@property (weak, nonatomic) IBOutlet UITextField *inputTF;
@end
@implementation SubViewController
- (IBAction)backAction:(id)sender {
if ([self.delegate respondsToSelector:@selector(subVC:AndValue:)]) {
[self.delegate subVC:self AndValue:self.inputTF.text];
[self.navigationController popViewControllerAnimated:YES];
}
}
题外话
iOS还有多播代理
的概念,想要了解更多代理应用的童鞋可以自行学习了解一下
网友评论