谈KVC、KVO(重点观察者模式)机制编程

一不小心,小明在《跟着贝尔去冒险》这个真人秀节目中看到了“一日警察,一世警察”的Laughing哥,整个节目除了贝尔吃牛睾丸都不用刀叉的不雅餐饮文化外,还是镜头少普通话跟小明一样烂的Laughing Sir那种冷静和沉着稳定留下了深刻印象,不由想起电视剧《学警狙击》中为了不暴露钟立文的身份,要求向自己补一枪的警匪卧底巅峰推动者--Laughing 哥。
那么,卧底这样的工作,在我们程序里有没有呢?答案是肯定的,观察者模式。

文章内容思维导图

一.基本概念

1)KVC概念
  1. KVC全称Key-value coding.
  1. 一个非正式的Protocol,提供一种机制来间接访问对象的属性.

官方文档提供对KVC很准确的描述

Key-value coding is a mechanism for accessing an object’s properties indirectly, using strings to identify properties, rather than through invocation of an accessor method or accessing them directly through instance variables. In essence, key-value coding defines the patterns and method signatures that your application’s accessor methods implement.

2)KVO概念
  1. KVO全称Key-Value Observing。
  1. 典型的观察者模式承载者。
  2. 基于监控键值发生变化,通知观察者。
  3. KVO 就是基于 KVC 实现的关键技术之一。

官方文档提供对KVO很准确的描述

Key-value observing provides a mechanism that allows objects to be notified of changes to specific properties of other objects. It is particularly useful for communication between model and controller layers in an application.

二.KVC和KVO的作用

Laughing哥上场了,先看看怎么做卧底,首先,Laughing哥先得符合古惑仔行为准则混入黑帮;接着,除了放高利贷和Disco业务外最重的是挤兑从台湾出狱的世孝,选择站在亦天内心的一边得到足够多的信任;最后,凭借“一日警察,一世警察”赤诚初心,秉公执法端掉亦天和制毒窝点。

那么,你觉度Laughing Sir的作用是什么?

1. 接近需要得到信息隐秘或不隐秘的使用场所。
2. 直接监视信息的变化。
3. 当产生了有用的信息后,那马上通知汇报。

如果亦天制作的毒品比作信息,普通警察只能通过get方式属性,更重要是不知道他什么时候发生了变化。卧底Laughing Sir完美扮演的就是KVC和KVO机制,为什么说完美?KVC是可以直接通过路径获取对应的键的值,KVO的观察通知部分就对应Laughing Sir的监视和汇报,如果Laughing Sir变节了或者没有意志做下去了,那就只能是KVC能获取到信息,但不能通知上级信息的变化,就没有了一个经典的卧底角色Laughing了。

三.JAVA中的观察着模式

Sun公司早早就把观察者模式视为重要的模式,并在Java中提供方便的接口Observer和类Observable。这个地方注意一下,Observer是一个接口,Observable是一个类。因为很容易先入为主,XXXable第一反应是接口。如果看过《设计模式之禅》这本书的人,自然想起书中举的例子是李斯监视同窗韩非子的一举一动汇报给秦始皇。并且书中的Observer和Observable自定义定义刚好相反,注意下即可。为什么提Java,继续看吧。

四.代码实现

1. KVC属性读取和修改

1)Sense:
警官:梁笑棠,从今天开始 ,你的生命属于社会的,清楚吗?  
Laughing Sir:清楚。  
警官:出了这个学堂,你要叫Laughing 哥,记好了吗?  
Laughing Sir:Yes sir。
警官:你妹,大声点。  
Laughing Sir:_____

程序中,Laughing Sir被派于卧底工作前,需要把Laughing Sir的名字属性值更换成Laughing哥.我们就从这个地方开始练练手预热做卧底的体验吧。

2)Step:

①通过路径方式获取属性值

NSString *preName = [laughingSir valueForKey:@"name"];

②修改属性值

[laughingSir setValue:@"laughing 哥" forKey:@"name"];  
3)Show Code:
NSString* exchangeName(LaughingSir *laughingSir){

    NSString *preName = [laughingSir valueForKey:@"name"];
    NSLog(@"laughing的旧名字:%@",preName);

    [laughingSir setValue:@"laughing 哥" forKey:@"name"];

    NSString *newName = [laughingSir valueForKey:@"name"];
    NSLog(@"laughing的新名字:%@",newName);

    return newName;
}

2.KVO观察者模式演绎

1)Sense:
亦天可能进行制毒。。。
Laughing Sir开始监控亦天
报告上级亦天制毒数:___  

程序中,Laughing Sir开始观察YiTian这个实体类中的narcotics属性,一旦亦天制作出毒品,就马上observeValueForKeyPath通知上级,看看如下的具体实现。

2)Step:

①对被观察者添加观察

[self.yiTian addObserver:self forKeyPath:@"narcotics" options:NSKeyValueObservingOptionNew |NSKeyValueObservingOptionOld context:nil];  

②实现观察结果处理方法

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{
    //汇报上级
}
3)Show Code:
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context{
    if([keyPath isEqualToString:@"narcotics"]){
    
        NSNumber *narcoticsN = [change objectForKey:@"new"];//修改之后的最新值
        NSInteger narcotics = [narcoticsN integerValue];
        if (narcotics>0) {
            if (self.delegate!=nil&&[self.delegate respondsToSelector:@selector(reportYitian:)]) {
                [self.delegate reportYitian:narcotics];
            }
        }
    }
}  

注意:留意下[change objectForKey:@"new"]其中这个new是指新赋予narcotics这个属性的值,当然也有一个old而不是[change objectForKey:@"narcotics"];narcotics是毒品意思。

3.Java实现观察者模式

这里我就直接显示关键代码了,不做过多说明,对比了解和学习。

/**
* 亦天实体类  
* @author minggo
* @time 2016年4月1日 上午10:24:15
 */
public class YITian extends Observable {

    private Observer observer;
    private int narcotics;

    @Override
    public synchronized void addObserver(Observer o) {
        super.addObserver(o);
        this.observer = o;
    }

    public void MakeNarcotics(){
        for (int i = 0; i <3; i++) {
            narcotics++;
            if (observer!=null) {
                observer.update(this, narcotics);
            }
        }
    }

}

留意Laughing Sir实体类的@override方法

/**  
* Laughing Sir实体类  
* @author minggo  
* @time 2016年4月1日 上午9:58:36  
*/
public class LaughingSir implements Observer{
    @Override
    public void update(Observable o, Object arg) {
        if (o instanceof YITian) {
            System.out.println("监视到亦天制毒"+arg+"kg");
        }
    }
    public void watchOverYiTian(YITian yiTian){
        yiTian.addObserver(this);
    }
}

最后是测试main方法

/**  
* 观察者模式
* @author minggo
* @time 2016年4月1日 上午10:36:37
*/
public class TestOberving {

    public static void main(String[] args) {
    
        YITian yiTian = new YITian();
        LaughingSir laughingSir = new LaughingSir();
    
        //Laughing Sir卧底开始监视亦天的一举一动
        laughingSir.watchOverYiTian(yiTian);
        System.out.println("Laughing Sir卧底开始监视亦天的一举一动");
    
        System.out.println("-----------亦天开始制作毒品--------");
        //亦天开始制毒
        yiTian.MakeNarcotics();
        System.out.println("-----------亦天结束制作毒品--------");
    }
}

五.现状下观察者模式的重要性

就犹如Laughing哥这样的角色,观察者模式在实际应用中起到重要的作用。无论你之前发现了,还是现在察觉到它的不可忽视。移动开发的MVVM开发架构思想中的重要解耦页面部分,就是观察者模式实现数据绑定,即时刷新数据。这个在iOS中KVO和Android使用Java的Observer接口都异曲同工之意,RxJava的响应是编程的基本思想也是观察者模式之艺术。

现状下的热门的移动开发的关键字,透漏出观察者模式显得越来越重要。其中就包括面试门槛,曾经面试过Android开发者还是iOS开发者,问到观察者这个模式可有了解?有回答iOS观察就是KVO,Java的就是在被观察对象添加回调接口,也有说过《设计模式之禅》中的韩非子被李斯监视的例子。

今天,有多了一个,Laughing哥卧底神话,个人感情建议使用这个例子,呵呵~。

六.效果图更直观

效果图

七.源码下载地址更详细

https://github.com/minggo620/iOSObserving.git

Laughing哥如果见到我,估计会说:“小明,其实我真实的名字叫~谢天华!”


【原创出品 未经授权 禁止转载】
【欢迎微友分享转发 禁止公号等未经授权的转载】

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,015评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,262评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,727评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,986评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,363评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,610评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,871评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,582评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,297评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,551评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,053评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,385评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,035评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,079评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,841评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,648评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,550评论 2 270

推荐阅读更多精彩内容