一不小心般妙,小明在《跟著貝爾去冒險》這個真人秀節(jié)目中看到了“一日警察,一世警察”的Laughing哥相速,整個節(jié)目除了貝爾吃牛睪丸都不用刀叉的不雅餐飲文化外碟渺,還是鏡頭少普通話跟小明一樣爛的Laughing Sir那種冷靜和沉著穩(wěn)定留下了深刻印象,不由想起電視劇《學(xué)警狙擊》中為了不暴露鐘立文的身份突诬,要求向自己補一槍的警匪臥底巔峰推動者--Laughing 哥苫拍。
那么,臥底這樣的工作旺隙,在我們程序里有沒有呢绒极?答案是肯定的,觀察者模式蔬捷。
一.基本概念
1)KVC概念
- KVC全稱Key-value coding.
- 一個非正式的Protocol垄提,提供一種機制來間接訪問對象的屬性.
官方文檔提供對KVC很準(zhǔn)確的描述
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概念
- KVO全稱Key-Value Observing。
- 典型的觀察者模式承載者周拐。
- 基于監(jiān)控鍵值發(fā)生變化铡俐,通知觀察者。
- KVO 就是基于 KVC 實現(xiàn)的關(guān)鍵技術(shù)之一速妖。
官方文檔提供對KVO很準(zhǔn)確的描述
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哥先得符合古惑仔行為準(zhǔn)則混入黑幫;接著稿饰,除了放高利貸和Disco業(yè)務(wù)外最重的是擠兌從臺灣出獄的世孝锦秒,選擇站在亦天內(nèi)心的一邊得到足夠多的信任;最后喉镰,憑借“一日警察旅择,一世警察”赤誠初心,秉公執(zhí)法端掉亦天和制毒窩點侣姆。
那么生真,你覺度Laughing Sir的作用是什么沉噩?
1. 接近需要得到信息隱秘或不隱秘的使用場所。
2. 直接監(jiān)視信息的變化柱蟀。
3. 當(dāng)產(chǎn)生了有用的信息后川蒙,那馬上通知匯報。
如果亦天制作的毒品比作信息长已,普通警察只能通過get方式屬性畜眨,更重要是不知道他什么時候發(fā)生了變化。臥底Laughing Sir完美扮演的就是KVC和KVO機制术瓮,為什么說完美康聂?KVC是可以直接通過路徑獲取對應(yīng)的鍵的值,KVO的觀察通知部分就對應(yīng)Laughing Sir的監(jiān)視和匯報胞四,如果Laughing Sir變節(jié)了或者沒有意志做下去了恬汁,那就只能是KVC能獲取到信息,但不能通知上級信息的變化辜伟,就沒有了一個經(jīng)典的臥底角色Laughing了蕊连。
三.JAVA中的觀察著模式
Sun公司早早就把觀察者模式視為重要的模式,并在Java中提供方便的接口Observer和類Observable游昼。這個地方注意一下甘苍,Observer是一個接口,Observable是一個類烘豌。因為很容易先入為主载庭,XXXable第一反應(yīng)是接口。如果看過《設(shè)計模式之禪》這本書的人廊佩,自然想起書中舉的例子是李斯監(jiān)視同窗韓非子的一舉一動匯報給秦始皇囚聚。并且書中的Observer和Observable自定義定義剛好相反,注意下即可标锄。為什么提Java顽铸,繼續(xù)看吧。
四.代碼實現(xiàn)
1. KVC屬性讀取和修改
1)Sense:
警官:梁笑棠料皇,從今天開始 谓松,你的生命屬于社會的,清楚嗎践剂?
Laughing Sir:清楚鬼譬。
警官:出了這個學(xué)堂,你要叫Laughing 哥逊脯,記好了嗎优质?
Laughing Sir:Yes sir。
警官:你妹,大聲點巩螃。
Laughing Sir:_____
程序中演怎,Laughing Sir被派于臥底工作前,需要把Laughing Sir
的名字屬性值更換成Laughing哥
.我們就從這個地方開始練練手預(yù)熱做臥底的體驗吧避乏。
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:
亦天可能進(jìn)行制毒爷耀。。淑际。
Laughing Sir開始監(jiān)控亦天
報告上級亦天制毒數(shù):___
程序中畏纲,Laughing Sir開始觀察YiTian這個實體類中的narcotics屬性,一旦亦天制作出毒品春缕,就馬上observeValueForKeyPath通知上級盗胀,看看如下的具體實現(xiàn)。
2)Step:
①對被觀察者添加觀察
[self.yiTian addObserver:self forKeyPath:@"narcotics" options:NSKeyValueObservingOptionNew |NSKeyValueObservingOptionOld context:nil];
②實現(xiàn)觀察結(jié)果處理方法
-(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這個屬性的值锄贼,當(dāng)然也有一個old而不是[change objectForKey:@"narcotics"]票灰;narcotics是毒品意思。
3.Java實現(xiàn)觀察者模式
這里我就直接顯示關(guān)鍵代碼了宅荤,不做過多說明屑迂,對比了解和學(xué)習(xí)。
/**
* 亦天實體類
* @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("監(jiān)視到亦天制毒"+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臥底開始監(jiān)視亦天的一舉一動
laughingSir.watchOverYiTian(yiTian);
System.out.println("Laughing Sir臥底開始監(jiān)視亦天的一舉一動");
System.out.println("-----------亦天開始制作毒品--------");
//亦天開始制毒
yiTian.MakeNarcotics();
System.out.println("-----------亦天結(jié)束制作毒品--------");
}
}
五.現(xiàn)狀下觀察者模式的重要性
就猶如Laughing哥這樣的角色冯键,觀察者模式在實際應(yīng)用中起到重要的作用惹盼。無論你之前發(fā)現(xiàn)了,還是現(xiàn)在察覺到它的不可忽視惫确。移動開發(fā)的MVVM開發(fā)架構(gòu)思想中的重要解耦頁面部分手报,就是觀察者模式實現(xiàn)數(shù)據(jù)綁定,即時刷新數(shù)據(jù)改化。這個在iOS中KVO和Android使用Java的Observer接口都異曲同工之意掩蛤,RxJava的響應(yīng)是編程的基本思想也是觀察者模式之藝術(shù)。
現(xiàn)狀下的熱門的移動開發(fā)的關(guān)鍵字陈肛,透漏出觀察者模式顯得越來越重要揍鸟。其中就包括面試門檻,曾經(jīng)面試過Android開發(fā)者還是iOS開發(fā)者句旱,問到觀察者這個模式可有了解阳藻?有回答iOS觀察就是KVO,Java的就是在被觀察對象添加回調(diào)接口前翎,也有說過《設(shè)計模式之禪》中的韓非子被李斯監(jiān)視的例子稚配。
今天,有多了一個港华,Laughing哥臥底神話,個人感情建議使用這個例子午衰,呵呵~立宜。
六.效果圖更直觀
七.源碼下載地址更詳細(xì)
https://github.com/minggo620/iOSObserving.git
Laughing哥如果見到我冒萄,估計會說:“小明,其實我真實的名字叫~謝天華橙数!”
【原創(chuàng)出品 未經(jīng)授權(quán) 禁止轉(zhuǎn)載】
【歡迎微友分享轉(zhuǎn)發(fā) 禁止公號等未經(jīng)授權(quán)的轉(zhuǎn)載】