黑马软件工程师 委托模式--类别、协议、Block篇

黑马程序员 委托模式--类别、协议、Block篇

---------------------- <a href="http://www.itheima.com"target="blank">ASP.Net+Unity开发</a>、

<a href="http://www.itheima.com"target="blank">.Net培训</a>、期待与您交流! -----------------------   

委托模式--类别、协议、Block篇

委托,什么是委托?xxx委托谁做件事,这是我们常见的一种形式,从这里我们可以知道,委托是双方的。OC中的委托(delegation)经常与协议一起用的特性,委托的定义是一个类指定另一个类处理某些特定的任务的设计模式。这几天刚好学到有关类别、协议(都指正式协议)和代码块(block)的知识,而这几个知识点有和委托有密不可分的关系,所以我今天我尝试写了个有代理模式(委托)的程序。程序的内容是这样的,有一个小孩,一个保姆,一个妈妈,用代理模式(委托)处理当孩子哭了这样的情况。

我首先想到的用的就是协议,因为老师讲代理模式(委托)的时候都用的协议,所以先用协议来实现这个问题。对此我们得先理一理思路,我尽量用面向对象思想来解决喽,首先这个问题中几个对象呢?有妈妈:Mother、有小孩:Baby、有保姆:BabyNurse。所以这个问题有三个类。它们分别拥有的内容是什么呢,对于这个问题中得小孩,有哭这样得动作:cry,为了在前后对比,我给小孩填了个笑得动作:smile。其次是妈妈,妈妈应该有小孩和指定保姆得权利,还有义务在小孩哭得时候做出一些处理,所以我给妈妈设了两个成员变量:一个小孩:baby,一个是会应付会哭得得保姆:delegateMother。对于处理小孩哭着这个动作:findBabyCry。最后是保姆,保姆会干嘛呢?会做家务:dohomework。但是这里要的不是这点,要会照顾会哭的小孩。所以她得学会怎样应付哭小孩的动作,比如喂奶:nurse,和她玩耍:playWithBaby等。而这些动作又不是所有的保姆所必须的,所以用协议的来封装这些哄小孩的技能。清楚这些之后,我们来得出这个问题的算法(解决步骤)。当小孩哭了,这个动作妈妈发现了,它会委托那个他请来会应付会哭小孩的保姆去处理(也许只要动一动嘴皮就行:小孩哭了,你去看看),然后保姆就会把它学会的哄小孩技能来哄这个小孩,然后小孩就笑了。具体请看代码。

小孩Baby类的头文件:

@interface Baby : NSObject

- (void) cry;

- (void) smile;

@end

妈妈Mother类的头文件:

@interface Mother : NSObject

@property (retain,nonatomic) Baby *baby;

@property (retain,nonatomic) BabyNurse<MakeBabyHappy> *delegateMother;

// when mother find baby crying,delegateMother will works

- (void) findBabyCry;

@end

保姆BabyNurse头文件:

@interface BabyNurse : NSObject <MakeBabyHappy>

- (void) doHomeWork;

- (void) copeWithBabyCrying: (Baby *)baby;

@end

哄小孩的MakeBabyHappy协议文件:

@protocol MakeBabyHappy <NSObject>

@optional

// nurse to baby

- (void) nurse;

// play with baby

- (void) playWithBaby;

@end

代理模式的核心就是妈妈发现小孩了哭了的处理:findBabyCry

// when mother find baby crying,delegateMother will works

- (void)findBabyCry

{

    NSLog(@"I am in Mother-----");

    [self.baby cry];

    [self.delegateMother copeWithBabyCrying:_baby]; // 叫保姆就行了

}

以上就是用协议完成的一个代理模式(委托)的程序,其实思想还是很符合现实生活的,现在不是专门带小孩的保姆嘛,妈妈把小孩委托给保姆照顾,至于保姆怎样把孩子带好,是保姆的事,妈妈需要担心。对于以上用协议完成的过程,用非正式协议也能左,那什么事非正式协议呢?前面的博客有讲,非正式协议指的是NSObject的类别。所以对于上面保姆要做的事我们可以通过非正协议来实现,同样也能完成所要的目的,哄小孩不哭。采用这种非正式协议的方式虽然实现了委托方法,但是不像代理模式那样双方的委托,它更像是一种一个妈妈学习得到哄小孩这样的技能。而这个技能就是NSObject的类别:MakeBabyHappy,里面有哄小孩技能:喂奶:nurse,和她玩耍:playWithBaby。

@interface NSObject (MakeBabyHappy)

// nurse to baby

- (void) nurse;

// play with baby

- (void) playWithBaby;

@end

妈妈Mother1类实现(也是核心哦):

@implementation Mother1

- (void)findBabyCry

{

    NSLog(@"I am a mother with genius about take care baby");

    [self.baby cry];

    [self nurse];

    [self playWithBaby];

    [self.baby smile];

}

@end

至于用代码块(block),我直接上代码:

小孩Baby上 面有

保姆Nurse类的实现:

@implementation Nurse

- (void) copeBabyCryingUsingBlock: (void (^) ()) block

{

    NSLog(@"I am a nurse");

    block();

}

@end

妈妈Mother2类的实现:

- (void) findBabyCrying

{

    [self.baby cry];

    // if nurse is null,program will not error.it will skip below statement

     [self.nurse copeBabyCryingUsingBlock:^{

        NSLog(@"he must be hungry,you need to nurse some milk");

        // you can other things about making baby happy

    }];

    [self.baby smile];

}

我们可以看到用block它的哄小孩的实现是在妈妈类里面,也是在委托对象的内部,这样的好处是是的代码更加紧簇。

---------------------- <a href="http://www.itheima.com"target="blank">ASP.Net+Unity开发</a>、

<a href="http://www.itheima.com"target="blank">.Net培训</a>、期待与您交流! -----------------------