zoukankan      html  css  js  c++  java
  • OC学习篇之---代理模式

    何实现代理模式的。

    这里举一个简单的例子:

    小孩类,护士类,保姆类,其中小孩类有两个方法:wash和play

    这里代理对象就是:护士类、保姆类,小孩类是被代理对象。

    看一下代码:

    首先看一下小孩类:

    Children.h

    [objc] view plain copy
     
    1. //  
    2. //  Children.h  
    3. //  12_DesignStyle  
    4. //  
    5. //  Created by jiangwei on 14-10-11.  
    6. //  Copyright (c) 2014年 jiangwei. All rights reserved.  
    7. //  
    8.   
    9. #import <Foundation/Foundation.h>  
    10.   
    11. @class Children;//如果没有这行代码的话,协议ChildrenDelegate中得Children类型就会查找不到,报错  
    12.   
    13. @protocol ChildrenDelegate <NSObject>  
    14.   
    15. @required  
    16. - (void)wash:(Children *)children;  
    17. - (void)play:(Children *)children;  
    18.   
    19. @end  
    20.   
    21. @interface Children : NSObject{  
    22.       
    23.     //Nure *_nure;//保姆  
    24.     //这里可以使用多态技术实现,因为保姆,护士有共同的父类NSObject,但是这里不使用这种方式,而是使用id类型  
    25.     //但是我们还需要为这个类型添加一些方法,这里就用到了协议  
    26.     //这个代理对象必须遵从ChildrenDelegate协议  
    27.     id<ChildrenDelegate> _delegate;//这个变量就是小孩的代理对象  
    28.     NSInteger timeValue;  
    29. }  
    30.   
    31. -(void)setDelegate:(id)delegate;  
    32.   
    33. @end  

    这里,我们定义了一个协议:ChildrenDelegate,他有两个必要的方法:wash和play

    我们还定义了一个很重要的属性

    _delegate

    这个属性定义有点不一样,这个就是实现代理对象的精髓所在了,id是不确定类型,所以这个_delegate变量可以被赋值为的类型是:

    只要实现了ChildrenDelegate协议的类就可以了。这里就记住了,以后这种定义方法后面会用到很多。相当于Java中的接口类型,只能赋值其实现类的类型。只是这里的定义格式为:id<协议名>

    然后就是一个设置协议的方法了,注意参数类型也必须是id的

    其实这里面也牵涉到了之前说到的多态特性,所以说代理模式也是建立在多态的特性上的。

    Children.m

    [objc] view plain copy
     
    1. //  
    2. //  Children.m  
    3. //  12_DesignStyle  
    4. //  
    5. //  Created by jiangwei on 14-10-11.  
    6. //  Copyright (c) 2014年 jiangwei. All rights reserved.  
    7. //  
    8.   
    9. #import "Children.h"  
    10.   
    11. //这里用到了保姆的一些动作  
    12. //假如现在想请一个护士,那么我们又要去从新去请一个护士,那么这里面代码需要改,把保姆的地方换成护士的地方  
    13. //产生的原因就是因为耦合度太高了,保姆和孩子耦合在一起,如果需要换的话,就需要改动代码  
    14. //  
    15. @implementation Children  
    16.   
    17. - (id)init{  
    18.     self = [super init];  
    19.     if(self != nil){  
    20.         [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerAction:) userInfo:nil repeats:YES];  
    21.     }  
    22.     return self;  
    23. }  
    24.   
    25. -(void)setDelegate:(id)delegate{  
    26.     _delegate = delegate;  
    27. }  
    28.   
    29. - (void)timerAction:(NSTimer *)timer{  
    30.     timeValue++;  
    31.     if(timeValue == 5){  
    32.         [_delegate wash:self];  
    33.     }  
    34.     if(timeValue == 10){  
    35.         [_delegate play:self];  
    36.     }  
    37. }  
    38.   
    39. @end  

    我们自定义了一个初始化方法,在初始化方法中我们做了一个定时器的工作。

    [java] view plain copy
     
    1. [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(timerAction:) userInfo:nil repeats:YES];  

    这个就是OC中启动一个简单的计时器:每隔1s中就去执行一次self中的timerAction方法。

    OC中的定时器和java不一样,他的执行逻辑可以单独的在一个指定的方法中去做(C中的函数指针差不多,只要传递一个函数指针过来,就可以执行指定的函数,所以@selector做的工作就是这个),但是Java中必须实现Runable接口,在run方法中执行指定的逻辑代码。

    在timerAction方法中,我们是判断当时间到5s了,就执行代理对象的wash方法,10s的时候执行play方法。

    在来看一下护士类:

    Nure.h

    [objc] view plain copy
     
    1. //  
    2. //  Nure.h  
    3. //  12_DesignStyle  
    4. //  
    5. //  Created by jiangwei on 14-10-11.  
    6. //  Copyright (c) 2014年 jiangwei. All rights reserved.  
    7. //  
    8.   
    9. #import <Foundation/Foundation.h>  
    10.   
    11. #import "Children.h"  
    12.   
    13. @interface Nure : NSObject<ChildrenDelegate>  
    14.   
    15. - (void)wash:(Children *)children;  
    16. - (void)play:(Children *)children;  
    17.   
    18. @end  

    护士类很简单,实现ChildrenDelegate协议

    Nure.m

    [objc] view plain copy
     
    1. //  
    2. //  Nure.m  
    3. //  12_DesignStyle  
    4. //  
    5. //  Created by jiangwei on 14-10-11.  
    6. //  Copyright (c) 2014年 jiangwei. All rights reserved.  
    7. //  
    8.   
    9. #import "Nure.h"  
    10.   
    11. #import "Children.h"  
    12.   
    13. @implementation Nure  
    14.   
    15. - (void)wash:(Children *)children{  
    16.     NSLog(@"小孩脏了,保姆帮小孩洗澡");  
    17. }  
    18.   
    19. - (void)play:(Children *)children{  
    20.     NSLog(@"小孩哭了,保姆和小孩玩耍");  
    21. }  
    22.   
    23. @end  

    在这里就去实现wash和play方法了

    在来看一下保姆类:

    Nanny.h

    [objc] view plain copy
     
    1. //  
    2. //  Nanny.h  
    3. //  12_DesignStyle  
    4. //  
    5. //  Created by jiangwei on 14-10-11.  
    6. //  Copyright (c) 2014年 jiangwei. All rights reserved.  
    7. //  
    8.   
    9. #import <Foundation/Foundation.h>  
    10.   
    11. #import "Children.h"  
    12.   
    13. @interface Nanny : NSObject<ChildrenDelegate>  
    14.   
    15. - (void)wash:(Children *)children;  
    16. - (void)play:(Children *)children;  
    17.   
    18. @end  


    Nanny.m

    [objc] view plain copy
     
    1. //  
    2. //  Nanny.m  
    3. //  12_DesignStyle  
    4. //  
    5. //  Created by jiangwei on 14-10-11.  
    6. //  Copyright (c) 2014年 jiangwei. All rights reserved.  
    7. //  
    8.   
    9. #import "Nanny.h"  
    10.   
    11. #import "Children.h"  
    12.   
    13. @implementation Nanny  
    14.   
    15. - (void)wash:(Children *)children{  
    16.     NSLog(@"小孩脏了,护士帮小孩洗澡");  
    17. }  
    18.   
    19. - (void)play:(Children *)children{  
    20.     NSLog(@"小孩哭了,护士和小孩玩耍");  
    21. }  
    22.   
    23. @end  

    保姆类和护士类的代码逻辑是一样的,因为他们两个都是实现了一个协议

    测试类

    main.m

    [objc] view plain copy
     
    1. //  
    2. //  main.m  
    3. //  12_DesignStyle  
    4. //  
    5. //  Created by jiangwei on 14-10-11.  
    6. //  Copyright (c) 2014年 jiangwei. All rights reserved.  
    7. //  
    8.   
    9. #import <Foundation/Foundation.h>  
    10.   
    11. #import "Children.h"  
    12. #import "Nure.h"  
    13. #import "Nanny.h"  
    14.   
    15. //核心:id类型+协议  
    16. //做到低耦合操作  
    17. //同时也可以做到两个类之间的通信  
    18.   
    19. int main(int argc, const charchar * argv[]) {  
    20.     @autoreleasepool {  
    21.         Children *child = [[Children alloc] init];  
    22.           
    23.         Nure *nure = [[Nure alloc] init];  
    24.         Nanny *nanny= [[Nanny alloc] init];  
    25.           
    26.         [child setDelegate:nanny];  
    27. //      [child setNure:nure];  
    28.           
    29.         [[NSRunLoop currentRunLoop] run];  
    30.     }  
    31.     return 0;  
    32. }  

    看到了,测试类很简单。我们也发现了,代理模式的好处也是显现出来了,比如现在又来了一个人来照顾孩子:妈妈类,那么我们只要让妈妈类实现那个协议即可。这种耦合度也不会很高。所以代理模式还是超级有用的,而且我们后面在开发IOS的时候,会发现他里面用到的代理模式很多的。

    运行结果:

  • 相关阅读:
    构建单页面应用
    chrome进入控制台时自动进入断点模式的解决方法
    git安装--linux下的安装
    express响应前端ajax请求
    nodejs链接mongodb数据库
    Redis的Java客户端Jedis的八种调用方式(事务、管道、分布式)介绍
    Nginx中如何限制某个IP同一时间段的访问次数
    nodejs && apidoc
    apidoc
    android sdk
  • 原文地址:https://www.cnblogs.com/anakin/p/7815460.html
Copyright © 2011-2022 走看看