观察者模式是设计模式的一种,又称为发布者/订阅者模式,其定义了一种一对多的关系,多个观察者可以监听一个对象。当该对象的状态发生改变时,会通知所有的观察者,观察者会自己进行更新。

观察者模式能够将观察者和被观察者解耦,被观察者不需要知道观察者是如何更新的,只需要在自己的状态发生改变时,通知观察者即可。

在实际工作中,当一个对象的改变,同时需要改变其他对象,且不确定有多少对象需要改变的时候,可以使用观察者模式。

在实现观察者模式时,观察者需要实现相应的更新方法;被观察者需要实现增加观察者、移除观察者、向观察者发送通知的方法。

举个例子,有两个模型对象,分别是老师和学生,其中学生是观察者,老师是被观察者。当老师的手机号发生改变时,会向学生发出通知,这样所有学生的“老师的电话号”这个属性就会更新。

实现代码:

观察者对象:

- (instancetype)initWithName:(NSString *)name
{
if(self = [super init]){
self.name = name;
self.teacherNum = @"";
}
return self;
}
// 观察者实现更新方法
- (void)updateTeacherPhone:(NSString *)phone
{
self.teacherNum = phone;
}

被观察者对象:

- (instancetype)initWithName:(NSString *)name
{
if(self = [super init]){
self.name = name;
self.phoneNum = @"";
self.observersArray = [NSMutableArray array];
}
return self;
} // 增加观察者对象
- (void)addObserver:(Student *)stu
{
if(![self.observersArray containsObject:stu]){
[self.observersArray addObject:stu];
}
} // 移除某个观察者对象
- (void)removeObserver:(Student *)stu
{
if([self.observersArray containsObject:stu]){
[self.observersArray removeObject:stu];
}
} // 向所有的观察者对象发出通知
- (void)notificationObserver
{
for(int i = 0; i < self.observersArray.count ; ++i){
Student *stu = [self.observersArray objectAtIndex:i];
if([stu respondsToSelector:@selector(updateTeacherPhone:)]){
[stu updateTeacherPhone:self.phoneNum];
}
}
}

在main函数中调用:

    Student *jhon = [[Student alloc] initWithName:@"jhon"];
Student *tom = [[Student alloc] initWithName:@"tom"];
Teacher *teacher = [[Teacher alloc] initWithName:@"Green"];
// 增加观察者
[teacher addObserver:jhon];
[teacher addObserver:tom];
teacher.phoneNum = @"123456";
// 通知所有的观察者进行更新
[teacher notificationObserver];
NSLog(@"jhon teacherPhone = %@",jhon.teacherNum);
NSLog(@"tom teacherPhone = %@",tom.teacherNum);
// 移除一个观察者
[teacher removeObserver:jhon];
teacher.phoneNum = @"654321";
// 通知所有的观察者进行更新
[teacher notificationObserver];
NSLog(@"jhon teacherPhone = %@",jhon.teacherNum);
NSLog(@"tom teacherPhone = %@",tom.teacherNum);

输出结果:  

jhon teacherPhone = 123456
tom teacherPhone = 123456
jhon teacherPhone = 123456
tom teacherPhone = 654321

可以看到,被观察者将某个观察者移除后,被观察者状态发生改变并通知观察者,被移除的观察者状态不变。

实际上,在iOS开发中,KVO以及消息中心都是使用观察者模式实现的。

ObjC-观察者模式的更多相关文章

  1. obj-c编程18:多对多的观察者模式

    我们知道使用委托的设计模式可以实现一对一的通知关系,但是如果需要通知多个观察者状态变化又该如何呢?此时,需要实现观察者模式之类的内容,而不是实现委托者一对一的模式. 观察者模式定义了一个对象可以将另一 ...

  2. 设计模式-(10)观察者模式 (swift版)

    一,概念 观察者(Observer)模式又名发布-订阅(Publish/Subscribe)模式.GOF给观察者模式如下定义:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它 ...

  3. 23种设计模式--观察者模式-Observer Pattern

    一.观察者模式的介绍      观察者模式从字面的意思上理解,肯定有两个对象一个是观察者,另外一个是被观察者,观察者模式就是当被观察者发生改变得时候发送通知给观察者,当然这个观察者可以是多个对象,在项 ...

  4. 谈谈JS的观察者模式(自定义事件)

    呼呼...前不久参加了一个笔试,里面有一到JS编程题,当时看着题目就蒙圈...后来研究了一下,原来就是所谓的观察者模式.就记下来...^_^ 题目 [附加题] 请实现下面的自定义事件 Event 对象 ...

  5. ObserverPattern(观察者模式)

    import java.util.ArrayList; import java.util.List; /** * 观察者模式 * @author TMAC-J * 牵一发而动全身来形容观察者模式在合适 ...

  6. java观察者模式

      像activeMQ等消息队列中,我们经常会使用发布订阅模式,但是你有没有想过,客户端时如何及时得到订阅的主题的信息?其实就里就用到了观察者模式.在软件系统中,当一个对象的行为依赖于另一个对象的状态 ...

  7. Backbone源码解析(六):观察者模式应用

    卤煮在大概一年前写过backbone的源码分析,里面讲的是对一些backbone框架的方法的讲解.这几天重新看了几遍backbone的源码,才发现之前对于它的理解不够深入,只关注了它的一些部分的细节和 ...

  8. PHP 高级编程(3/5) - 使用SPL(标准PHP库)实现观察者模式

    SPL(标准PHP库 - Standard PHP Library)是PHP5面向对象功能中重要的部分.原文解释是这样的“The Standard PHP Library (SPL) is a col ...

  9. 由objC运行时所想到的。。。

    objC语言不仅仅有着面向对象的特点(封装,继承和多态),也拥有类似脚本语言的灵活(运行时),这让objC有着很多奇特的功能-可在运行时添加给类或对象添加方法,甚至可以添加类方法,甚至可以动态创建类. ...

  10. objC与js通信实现--WebViewJavascriptBridge

    场景   在移动端开发中,最为流行的开发模式就是hybmid开发,在这种native和h5的杂糅下,既能在某些需求中保证足够的性能,也可以在某些列表详情的需求下采用h5的样式控制来丰富内容.但是在大型 ...

随机推荐

  1. uva10375 Choose and divide

    唯一分解定理. 挨个记录下每个质数的指数. #include<cstdio> #include<algorithm> #include<cstring> #incl ...

  2. UVa 1103 (利用连通块来判断字符) Ancient Messages

    本题就是灵活运用DFS来求连通块来求解的. 题意: 给出一幅黑白图像,每行相邻的四个点压缩成一个十六进制的字符.然后还有题中图示的6中古老的字符,按字母表顺序输出这些字符的标号. 分析: 首先图像是被 ...

  3. Share SDK 第三方登录

    import java.util.HashMap; import org.apache.http.Header; import android.app.Activity; import android ...

  4. hdu 4612 Warm up(缩点+树上最长链)

    本来就是自己负责图论,结果水了= = 题目其实很裸,就是求桥的数量,只是要新加上一条边罢了.做法:先缩点.再在树上搜最长链(第一场多校的hdu 4607Park Visit就考了最长链,小样,套个马甲 ...

  5. C#进程启动程序,并禁止原窗口操作

    Process myProcess = new Process();            myProcess.StartInfo.FileName = exeName;            myP ...

  6. IOS cocos2d笔记1

    结点添加.删除.获取1.结点:CCNode * childNode = [CCNode node]; 2.加入结点[myNode addChild:childNode z:0 tag:123];//z ...

  7. LeetCode: Word Break I && II

    I title: https://leetcode.com/problems/word-break/ Given a string s and a dictionary of words dict, ...

  8. ffmpeg windows 雪花声解决方法

    替换所有文件里的<math.h>为<mathimf.h>即可. 我用ffmpeg-0.6.3版测试时,好像mathimf.h文件和其他文件有冲突,需要修改源码. 和qdm2.c ...

  9. 开源Jabber(XMPP) IM服务器介绍

    一.摘要 这是我粗略读了一遍Jabber协议和相关技术文章后的产物,有些地方不一定准确.在文章中引用的一些代码来自www.jabber.org上的文章. 二. 什么是Jabber    Jabber就 ...

  10. CoreData 基本操作方法封装

    转:http://blog.csdn.net/marujunyy/article/details/18500523 为了方便使用CoreData 封装了几个扩展类,使用方法和类文件如下: //首先需要 ...