IOS设计模式-观察者模式

简介:

前言:23种软件设计模式中的观察者模式,也是在软件开发中,挺常用的一种设计模式。而在苹果开发中,苹果Cocoa框架已经给我们实现了这个设 计模式,那就是通知和KVO(Key-Value Observing),本篇博文将会先讲解通知和KVO的常用方法和使用示例,然后讲解观察者模式以及对观察者模式的实现。

 

文章内容大纲:

1、KVO的使用

2、通知的使用

3、观察者模式

 

正文:

1、KVO的使用

addObserver:forKeyPath:options:context:

通知其他对象的方法,这个方法在NSObject中就已经申明了,也就是说任何继承自NSObject的对象都可以使用KVO.

我们来实现一个对象a值改变的时候去通知对象b,也就是说这里b就是a的观察者,b观察a的变化,然后做出相应的反应.

Model_A.h和Model_A.m:

  

  Model_B.h和Model_B.m:

  

  最后在ViewController.h中:

  

  输出结果:

  2016-03-10 18:02:39.955 KVO[24772:539854] 程序开始执行!
2016-03-10 18:02:41.959 KVO[24772:539854] Model_B

   -----------------------------------------------------------------------------------------------------------------------------------------------------------

  如果注释掉Model_B中的方法observeValueForKeyPath:ofObject:change:context:,运行时会导致崩溃:

  

   也就是这么一层关系:

  A对象要通知B对象,B对象必须实现监听的方法,否则一旦有消息发送就会导致崩溃.

  A对象不想通知B对象了,需要从B对象身上移除掉通知.

 

  要想程序不出现问题,我们需要实现3步.

  (主动添加B的通知) A -------> B(不实现一个方法就崩溃)

  (主动移除B的通知) A ---X-->  B

(重复移除B的通知) A ---X-->  B(崩溃)

  用起来很恶性,还好,我们可以重复添加B的通知而不崩溃......

    但是要注意:添加的观察者的次数要和移除观察者的次数相等,少移除一个或者多移除一个都会造成程序崩溃:

   

   

 

2、 通知的使用

  Model.h和Model.m

  

  简易封装的通知中心类:Notification.h 和 Notification.m

  

  在ViewController.m中:

    

  输出结果:

  2016-03-10 20:36:20.077 通知[28333:641372] 
Hello,NSConcreteNotification 0x7fbafbd0b620 {name = A; userInfo = Hello,a}!
2016-03-10 20:36:20.078 通知[28333:641372] 
Hello,NSConcreteNotification 0x7fbafbd0bca0 {name = B; userInfo = Hello,b}!


3、观察者模式

  关于观察者模式,我们百度百科一下,会找到:

  观察者模式(有时又被称为发布(publish )-订阅(Subscribe)模式、模型-视图(View)模式、源-收听者(Listener)模式或从属者模式)是软件设计模式的一种。在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实现事件处理系统。

        

   在这个图示例中,"订阅书刊的用户"需要向"书刊发行机构"提供基本的注册信息,这些信息包括用户自己的基本信息和要"订阅的书刊号",然后确定成为" 书刊发行机构"的用户,然后当"书刊发行机构"开始发行书刊,就会根据"订阅书刊的用户"的已经提供过的基本信息,进行发行书刊。然后"订阅书刊的用户" 就会得到相应的书刊。

  在这个"发行-订阅"的模式中,"书刊发行机构"和"订阅书刊的用户"之间是靠"订阅书刊的用户"提供的基本有效的信息建立联系的。

  这个"发行-订阅"的模式也是一种观察者模式的一个生活中非常生动的例子。"书刊发行机构"相当于观察者模式中的一个"通知中心"的角色,会根据实际需求根据用户信息向用户发送消息,然后用户作为观察者收到这些消息之后,就会自动的根据消息来执行自己的业务逻辑。

  接下来,我们要实现通知中心的抽象设计

  根据需求分析,首先我们需要一个唯一的"书刊发行机构",然后可以增加和删除书刊,同时能存储多个书刊,然后每个书刊又可以对应多个"订阅书刊的用户",

   另外要补充一个就是,在添加和移除用户的接口中,我们需要传入用户信息对象,这个用户信息对象我们需要用协议来约束它,我们思考一下,比如订阅书刊,我 们当然需要用户最基本的两个信息,用户的ID和用户订阅的书刊号,用户的ID用于"书刊发行机构"能够准确的发消息或者发书刊正确无误的发对了人,这个作 用就好比我们唯一的身份证号码的作用是一样的。然后用户订阅的书刊号,就能保证"书刊发行机构"能把正确的书刊发到用户手中,不能随便什么书刊都发向随便 什么人的吧。

  所以先写出下面所有的公开的接口,后面再具体实现它们,这就是面向接口设计:

    

  另外,当"书刊发行机构"有了新的书刊的时候,根据需求,创建一个书刊号,然后如果有新的用户需要订阅新的书刊,根据需求,创建一个用户订阅书刊的信息对象。

  一个书刊对应每个月会在某一天发布新书,当"书刊发行机构"的现有的书刊有了新的书发布的时候,就会发消息通知订阅这个书刊的用户,然后用户会做出及时的响应回馈。

  按照观察者模式,被观察者发送消息,观察者收到消息就需要立马做出响应。这个和我们之前用的Cocoa框架已经实现的KVO和通知的模式是一样的。

  为了实现这样的模式,我们还需要给用户信息对象用一个协议来约束它:

  

  接着我们为上面的公开的接口具体实现,但是我们需要选择一个数据结构来存储书刊号和订阅书刊的用户信息对象,这里我选择使用NSMutableDictionary的Key-Value来存储书刊号和书刊,用NSHashTable来存储用户信息对象。

  那么为什么要用NSHashTable来存储用户信息呢?为什么不用别的数据结构,比如数组(NSMutableArray)或者字典(NSMutableDictionary).

    因为NSHashTable会对添加进的对象持有弱引用,当添加进来的元素,外部对他持有的强引用都取消的时候,这个对象就会自动从内存中消除,这样就不需要手动移除这些对象。

    这个相比Cocoa给我们实现的KVO和通知,就不需要我们手动去操作实现removeObserve方法了。

    虽然说,在使用NSHashTable实现的观察者模式,观察者对象本身就至少需要一个强引用,但是在实际开发中,观察者往往都至少会有一个强引用的。

    所以,使用NSHashTable对系统算是一个小小的优化。

  

  然后接着我们使用前面创造的观察者模式:

  CustomerA.h和CustomerA.m:

  

  在ViewController中,同时也把ViewController作为用户对象,以self传入:

  

  打印:

  2016-03-11 14:50:38.980 ObserverPattern[7958:175895] hashTable:NSHashTable {
  [5] <ViewController: 0x7f93d2d26ac0>
  [12] <CustomerA: 0x7f93d2c17f40>
  }
2016-03-11 14:50:38.981 ObserverPattern[7958:175895] V1.0  SCIENCE
2016-03-11 14:50:38.981 ObserverPattern[7958:175895] 
Hello,My Name is : CustomerA 
    V1.0--SCIENCE

 备份的源码链接: http://pan.baidu.com/s/1eQTnm50 密码: s7su

 

 

 

 4、自己实现KVO(以后有时间补上)

 

目录
打赏
0
0
0
0
21
分享
相关文章
设计模式:观察者模式
观察者模式属于行为型设计模式,用于建立对象间的一对多依赖关系。当主题(Subject)状态变化时,所有依赖的观察者(Observer)会自动收到通知并更新。
前端必须掌握的设计模式——观察者模式
观察者模式(Observer Pattern)是一种行为型设计模式,实现了一种订阅机制。它包含两个角色:**观察者**(订阅消息、接收通知并执行操作)和**被观察者**(维护观察者列表、发送通知)。两者通过一对多的关系实现解耦,当被观察者状态改变时,会通知所有订阅的观察者。例如,商店老板作为被观察者,记录客户的需求并在商品到货时通知他们。前端应用中,如DOM事件注册、MutationObserver等也体现了这一模式。
Java 设计模式——观察者模式:从优衣库不使用新疆棉事件看系统的动态响应
【11月更文挑战第17天】观察者模式是一种行为设计模式,定义了一对多的依赖关系,使多个观察者对象能直接监听并响应某一主题对象的状态变化。本文介绍了观察者模式的基本概念、商业系统中的应用实例,如优衣库事件中各相关方的动态响应,以及模式的优势和实际系统设计中的应用建议,包括事件驱动架构和消息队列的使用。
105 6
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
62 1
Kotlin - 改良设计模式 - 观察者模式
Kotlin - 改良设计模式 - 观察者模式
77 3
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
46 3
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
66 2
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
Kotlin教程笔记(52) - 改良设计模式 - 观察者模式
49 9
设计模式之观察者模式
【10月更文挑战第12天】 观察者模式是一种行为型设计模式,定义了一对多的依赖关系,当一个对象状态改变时,所有依赖它的对象都会自动更新。主要由主题(被观察者)和观察者组成,实现对象间的松耦合,广泛应用于用户界面、事件驱动系统和数据监控等领域。

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等