黑马程序员---OC Prorocol代理模式

                    ------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------


一、什么事代理模式?

        代理模式是在oc中经常遇到的一种设计模式,那什么叫做代理模式呢? 举个例子:有一个婴儿,他本身不会自己吃饭和洗澡等等一些事情,于是婴儿就请了一个保姆,于是婴儿和保姆之间商定了一个协议,协议中写明了保姆需要做什么事情, 而保姆就是这个代理人,  即:婴儿和保姆之间有个协议,保姆继承该协议,于是保姆就需要实现该协议中的条款成为代理人。 

二、 代理模式的关键点:

     A完成一件事,但是自己不能完成,于是他找个代理人B 替他完成这个事情,他们之间便有个协议 (protocol),B继承该协议来完成A代理给他的事情。  

三、实例分析

    下面来举一个经典的实例,妈妈和保姆的例子:妈妈把孩子委托给保姆照顾,于是将需要完成的事情写成一个协议:协议声明如下:
  #import <Foundation/Foundation.h>  
@protocol Job <NSObject>  
-(void)takeEat;  
-(void)takeSleep;  
-(void)takePlay;  
-(void)takeShower;  
@end  
我们再声明Nurse类 即代理的人: 
 #import <Foundation/Foundation.h>  
#import "Job.h"  
@interface Nurse : NSObject<Job>//实现该协议  
@end  


实现文件:

#import "Nurse.h"  
@implementation Nurse  
-(void)takeEat  
{  
    NSLog(@"小孩饿了,喂它吃饭");  
}  
-(void)takeSleep  
{  
    NSLog(@"小孩困了,哄他睡觉");  
}  
-(void)takePlay  
{  
    NSLog(@"小孩醒来了,陪他玩");  
}  
-(void)takeShower  
{  
    NSLog(@"晚上给小孩洗澡");  
}  
-(void)dealloc  
{  
    NSLog(@"Nurse is dealloc");  
}  
@end  

再声明一个morther类:
 
#import <Foundation/Foundation.h>  
#import "Job.h"  
@class Nurse;  
@interface Morther : NSObject  
{  
    NSString *name;  
    id<Job> delegate;   //此处声明一个代理人,从而mother可以让代理人完成需要代理的事情  
}  
-(id)initWithName:(NSString *)_name delagat:(id<Job>)_delagete;  //传入代理人  
@property(nonatomic,copy)NSString *name;  
-(void)delagateThings;// 被代理的事情  
@end  


//实现文件
 
#import "Morther.h"  
#import "Nurse.h"  
@implementation Morther  
-(id)initWithName:(NSString *)_name delagat:(id)_delagete  
{  
    self=[super init];  
    if (self) {  
        if (name!=_name) {  
            [name release];  
            name=[_name copy];  
            [delegate release];  
            delegate=[_delagete retain];  
        }  
    }  
    return self;  
}  
@synthesize name;  
-(void)dealloc  
{  
    [name release];  
    [delegate release];  
    NSLog(@"host is dealloc");  
}  
-(void)delagateThings  
{  
    int i;  
    switch (i) {  
        case 1:  
            [delegate takeEat];  
            break;  
        case 2:  
            [delegate takePlay];  
            break;  
        case 3:  
            [delegate takeShower];  
            break;  
        case 4:  
            [delegate takeSleep];  
            break;  
        default:  
            break;  
    }  
    i++;  
}  
@end  


看看 在 main 文件中是怎么实现的: 
 
#import <Foundation/Foundation.h>  
#import "Morther.h"  
#import "Nurse.h"  
#import "Job.h"  
int main (int argc, const charchar * argv[])  
{  
  
    @autoreleasepool {  
          
        NSString *name=[[NSString alloc] initWithFormat:@"小花"];  
        Nurse *fengjie=[[Nurse alloc] init];//代理人 fengjie  
        Morther *morther=[[Morther alloc] initWithName:name delagat:fengjie];//这样就将代理人传入mother 对象中,这样morther对象便可以通过nurse来完成她自己不能坐的事情了。  
        [name release];  
        [NSTimer scheduledTimerWithTimeInterval:2 target:morther selector:@selector(delagateThings)userInfo:nil repeats:YES];  //调用机制,  2秒调用一次, 调用的对象是morther , 调用的方法是delagateThings;  
        [[NSRunLoop currentRunLoop] run];  //让程序一直运行下去,保证上面的调用可以一直进行  
        [morther release];  
        [fengjie release];      
    }  
    return 0;  
}   


代理中,需要记住的关键是在发出代理请求的类(A)中声明代理人(B)的实例变量,这样就可以保证A 能通过调用B中B代理的方法来完成B代理的事情,即自己代理给B 的事情 

四、代理的应用(设计模式——代理模式)

MyProtocal1.h://这是协议类 
#import <Foundation/Foundation.h>  
@protocol MyProtocol1 <NSObject> //这是基协议,一定要遵守  
@required //默认required,必须要实现  
- (void)test1;  
- (void)test2;  
@optional //可选实现  
- (void)test3;  
@end  

MyProtocal2.h://这是协议类 
#import <Foundation/Foundation.h>  
@protocol MyProtocol2  
- (void)haha2;  
@optional  
- (void)haha3;  
@end  



只要一个类遵守了一份协议,就能拥有这份协议中的所有方法声明
协议不能写实现,仅仅添加方法声明
协议和分类一样,不能写成员变量
 : 继承父类
 <> 遵守协议

Person.h:

#import <Foundation/Foundation.h>  
#import "MyProtocol1.h"  
#import "MyProtocol2.h"  
@interface Person : NSObject <MyProtocol1,MyProtocol2> //类似java中的接口,OC也可以实现多个协议  
@end 

基本用途:
>可以声明一堆方法,单不能声明成员变量
>只要某个类遵守了这个协议,就相当于拥有这个协议中的所有方法声明
>只要父类遵守了某个协议,就相当于子类也遵守了
>用于代理模式和观察者模式
>一个协议可以遵守另一个协议:

@protocol MyProtocol2 <MyProtocol1>  
- (void)haha;  
@end  

5    代理模式设计

1、代理的设计原理:某个类不想亲自实现某些方法,就定义成员变量或者属性,该成员变量实现了这些方法,就可以通过成员变量去调用方法。这个成员变量指向的对象就叫做代理对象。
2、设计原则:
   (1) 得拥有某个代理对象属性
   (2)清楚代理有哪些方法
   (3)要保证能解耦
3、实现方案:
   (1) 定义一个protocol,在其中声明一些和代理沟通的方法
   (2) 拥有一个代理属性id delegate
   (3) 让代理遵守protocol


TicketDelegate.h 声明一些跑腿方法  

@protocol TicketDelegate <NSObject>   
  
// 返回票价  
- (double) ticketPrice;  
  
// 还剩多少张票  
- (int) leftTicketsNumber;  
  
@end  

Agent.h,代理对象  
@interface Agent : NSObject <TicketDelegate>   
  
@end  
  
@implementation Agent  
  
//Agent.m  
// 剩余的票数  
- (int)leftTicketsNumber  
{  
    // ... 亲自跑电影院\或者打电话  
      
    return 1;  
}  
  
// 每一张票多少钱  
- (double)ticketPrice  
{  
    // ... 亲自跑电影院\或者打电话  
    return 1000;  
}  
@end  


  NextAgent.h,代理对象  
@interface Agent : NSObject <TicketDelegate>   
  
@end  
  
@implementation Agent  
  
//NextAgent.m  
// 剩余的票数  
- (int)leftTicketsNumber  
{  
      
    return 500;  
}  
  
// 每一张票多少钱  
- (double)ticketPrice  
{  
      
    return 10;  
}  
@end  

Person.h  
@interface Person : NSObject  
  
- (void) buyTicket;  
  
// 拥有一个代理属性  
// id代表代理的类名随便  
// 但必须遵守TicketDelegate协议  
@property (nonatomic, retain) id<TicketDelegate>  delegate;  
  
@end  
  
//Person.m  
@implementation Person  
  
// 买电影票  
- (void)buyTicket  
{  
    // 叫代理去帮自己买票(询问一下票价、询问一下票的剩余张数)  
    double price = [_delegate ticketPrice];  
    int number =  [_delegate leftTicketsNumber];  
      
    NSLog(@"通过代理的帮忙,票价=%f,还剩%d张票", price, number);  
}  
  
- (void)dealloc  
{  
    [_delegate release];  
    [super dealloc];  
}  
@end  
  
int main(int argc, const charchar * argv[])  
{  
    // 人  
    Person *p = [[Person alloc] init];  
    // 代理  
    Agent *a = [[Agent alloc] init];  //第一个代理  
    NextAgent *na = [[NextAgent alloc] init];    //第二个代理    
    // 设置人的代理  
    p.delegate = a;  
      
    // 人打算看电影  
    [p buyTicket];  
      
    // 设置人的代理  
    p.delegate = na;  
      
    // 人打算看电影  
    [p buyTicket];      
    [a release];  
    [na release];  
    [p release];  
  
    return 0;  
}  
 




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值