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

文章内容思维导图

一.基本概念

1)KVC概念
  1. KVC全称Key-value coding.
  2. 一个非正式的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。
  2. 典型的观察者模式承载者。
  3. 基于监控键值发生变化,通知观察者。
  4. 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>) {
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 = ; i <; 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

谈KVC、KVO(重点观察者模式)机制编程的更多相关文章

  1. KVC/KVO原理详解及编程指南

    一.简介 1.KVC简介 2.KVO简介 二.KVC相关技术 1.Key和Key Path 2.点语法和KVC 3.一对多关系(To-Many)中的集合访问器方法 4.键值验证(Key-Value V ...

  2. 【转】 KVC/KVO原理详解及编程指南

    原文地址:http://blog.csdn.net/wzzvictory/article/details/9674431 前言: 1.本文基本不讲KVC/KVO的用法,只结合网上的资料说说对这种技术的 ...

  3. 转:KVC/KVO原理详解及编程指南

      作者:wangzz 原文地址:http://blog.csdn.net/wzzvictory/article/details/9674431 转载请注明出处 如果觉得文章对你有所帮助,请通过留言或 ...

  4. KVC, KVO 实现原理

    Key-Value Coding: 键值编码 (KVC) 方法调用: // 对象属性 // 类似: Person -> name setValue: forKey: // 对象的属性或者 属性的 ...

  5. 浅谈Linux中的信号处理机制(二)

    首先谢谢 @小尧弟 这位朋友对我昨天夜里写的一篇<浅谈Linux中的信号处理机制(一)>的指正,之前的题目我用的“浅析”一词,给人一种要剖析内核的感觉.本人自知功力不够,尚且不能对着Lin ...

  6. IOS开发之KVC KVO KVB

    KVC(Key Value Coding) KVO(Key Value Observing) KVB(Key Value Binding) KVO是Cocoa的一个重要机制,他提供了观察某一属性变化的 ...

  7. kvc/kvo复习

    kvc/kvo复习 1 小问题 '[<XMGPerson 0x7fb8a8f30220> setValue:forUndefinedKey:]: this XMGPerson * pers ...

  8. 阶段性总结⓵触摸事件&手势识别⓶Quartz2D绘图⓷CALayer图层⓸CAAnimation⓹UIDynamic UI动力学⓺KVC&KVO

    知识点复习   1. 触摸事件&手势识别   1> 4个触摸事件,针对视图的 2> 6个手势识别(除了用代码添加,也可以用Storyboard添加)   附加在某一个特定视图上的, ...

  9. Vue总结第五天:vue-router (使用模块化(创建Vue组件)机制编程)、router-link 标签的属性、路由代码跳转、懒加载、路由嵌套(子路由)、路由传递数据、导航守卫)

    Vue总结第五天:vue-router ✿ 路由(器)目录: □  vue中路由作用 □  vue-router基本使用 □  vue-router嵌套路由 □  vue-router参数传递 □  ...

随机推荐

  1. HDU 1536 sg-NIM博弈类

    题意:每次可以选择n种操作,玩m次,问谁必胜.c堆,每堆数量告诉. 题意:sg—NIM系列博弈模板题 把每堆看成一个点,求该点的sg值,异或每堆sg值. 将多维转化成一维,性质与原始NIM博弈一样. ...

  2. SVM核函数与软间隔

    核函数 在上文中我们已经了解到使用SVM处理线性可分的数据,而对于非线性数据需要引入核函数的概念它通过将数据映射到高维空间来实现线性可分.在线性不可分的情况下,支持向量机通过某种事先选择的非线性映射( ...

  3. Hadoop上路-03_Hadoop JavaAPI

    一.Eclipse安装 1.下载解压 下载:http://www.eclipse.org/downloads/ 解压:SHELL$ sudo tar -zxvf eclipse.tar.gz 2.快捷 ...

  4. 宏_CRTIMP分析

    CRTIMP是C run time implement的简写,C运行库的实现的意思. 作为用户代码,不应该使用这个东西. 该参数决定 运行时 到底用 动态链接库 还是静态链接 #ifndef _CRT ...

  5. iOS应用内HTTP服务上传文件

    相信很多朋友都用过AirAV.100tv这类iOS视频播放应用中通过Wifi,从PC上输入Web地址上传文件到iOS设备上,我也一直想实现这个功能,苦于知识掌握有限,后来在其他群友的指导下参照很多大神 ...

  6. CodeForces 589B Layer Cake (暴力)

    题意:给定 n 个矩形是a*b的,问你把每一块都分成一样的,然后全放一块,高度都是1,体积最大是多少. 析:这个题,当时并没有完全读懂题意,而且也不怎么会做,没想到就是一个暴力,先排序,先从大的开始选 ...

  7. 在SQL Server 2014下面使用的SQL2000的Northwind和Pubs示例数据库

    在SQL Server 2014下面使用的SQL2000的Northwind和Pubs示例数据库 http://files.cnblogs.com/files/lxzhangying/SQl2000S ...

  8. CSS基础(01)

    1. Css基础 1.1 CSS(层叠样式表 Multiple Styles)   CSS 是 Cascading Style Sheets(层叠样式表)的简称. CSS 语言是一种标记语言,它不需要 ...

  9. javascript:history.go(-1);

    history是你浏览过的网页的url(简单的说就是网址)的集合,也就是你的浏览器里的那个历史记录.它在js里是一个内置对象,就跟document一样,它有自己的方法,go就是其中一个. 这个方法的参 ...

  10. Python3向网页POST数据

    还是以我的网页iciba为例 POST数据到www.selflink.cn/iciba/get0.php获取返回的查询结果 #coding:utf8 import urllib.request imp ...