一不小心,小明在《跟着贝尔去冒险》这个真人秀节目中看到了“一日警察,一世警察”的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. PHP的MySQL扩展:PHP访问MySQL的常用扩展函数

    来源:http://www.ido321.com/1024.html 一.PHP连接数据库及基本操作 MySQL采用的是’客户机/服务器’架构.使用PHP安装的MySQL扩展函数,和直接使用客户端软件 ...

  2. 在windows7下配置PHP访问ICE中间件(ICE3.5.1+PHP5.4+Apache2.2 for vc9)

    按照ICE的官方文档(http://doc.zeroc.com/display/Ice/Using+the+Windows+Binary+Distribution#UsingtheWindowsBin ...

  3. C++ 我想这样用(五)

    上一篇说了[C with Class]语法的第一部分,下面继续第二部分: 第二部分:面向过程的编程风格 什么是面向过程我想如果你还不知道,那你绝对不是C程序员!其实我个人感觉面向过程.模块式的C编程风 ...

  4. TCPSocket v1.0 for cocos2d-x下载

    下载地址:http://files.cnblogs.com/elephant-x/TCPSocketLibs_V1.0.rar 这是自己封装的一个TCPSOCKET包,是独立于cocos2d-x的,使 ...

  5. 解决IE5、IE6、IE7与W3C标准的冲突,使用(IE7.js IE8.js)兼容

    如果分别用IE5.IE6.IE7浏览同一个网页,将可能出现不一样的效果. 这是它们之间对CSS的解析选择器不一样或错误和个别bug所导致.为了解决这些错误和bug. 我们不得不找到一个能平衡于它们之间 ...

  6. [COCOS2D-X]AssetsManager

    转自:http://blog.csdn.net/xpwang168/article/details/8900764 资源更新方式分析 I zip整包更新 优点:省流量,速度快 缺点:有重复资源,需要打 ...

  7. Spring入门(7)-自动检测Bean

    Spring入门(7)-自动检测Bean 本文介绍如何自动检测Bean. 0. 目录 使用component-scan自动扫描 为自动检测标注Bean 1. 使用component-scan自动扫描 ...

  8. jQuery基础学习3——jQuery库冲突

    默认情况下,jQuery用$作为自身的快捷方式. jQuery库在其他库之后导入 在其他库和jQuery库都被加载完毕后,可以在任何时候调用jQuery.noConflict()函数来将变量$的控制权 ...

  9. POJ 1502 MPI Maelstrom (Dijkstra)

    题目链接:http://poj.org/problem?id=1502 题意是给你n个点,然后是以下三角的形式输入i j以及权值,x就不算 #include <iostream> #inc ...

  10. FloatingActionButton的一点学习感悟

    最近在学习android材料设计的新控件,前面一篇文章讲到 CoordinatorLayout 结合几个新控件可以实现的几个效果.其中第一个是,Coordinatorlayout + Floating ...