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

来源:互联网 发布:数据挖掘导论百度云 编辑:程序博客网 时间:2024/05/22 05:26

                    ------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
原创粉丝点击