观察者模式

基本理解

  • 观察者模式又叫做发布-订阅(Publish/Subscribe)模式。
  • 观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,是他们能够自动更新自己。
  • 观察者只从通知器(发行商)把自己注册到(订阅)特定的通知(杂志)。当有通知的时候,观察者从通知器得到它订阅的通知。

观察者模式的特点

将一个系统分割成一系列相互协作的类有一个很不好的副作用,那就是需要维护相关对象间的一致性。我们不希望为了维护一致性而使各类紧密耦合,这样会给维护、扩展和重用都带来不便。

而观察者的关键是有一个对象(Model),它可以有多个观察者,一旦对象的状态发生了变化,那么所有的观察者都可以得到通知,及时更新。

使用场景

  • 当一个对象的改变需要同时改变其他对象的时候,我们就可以使用,而且不知道具体有多少个对象有待改变时,应该考虑使用观察者模式。
  • 观察者模式所做的工作就是在解除耦合。让耦合的双方都依赖于抽象,而不是依赖于具体。从而使得各自的变化都不会影响另一边的变化。
  • 例如,当用户点击视图上的排序按钮时,事件会传递给控制器,让模型在后台对其数据进行排序。当模型成功执行了对数据的操作后,它会通知所有相关的控制器,让他们用到的数据更新其视图。

在Cocoa Touch框架中使用观察者模式

Cocoa Touch框架用两种技术改写了观察者模式--通知和键值观察(KVO)。尽管是两种不同的Cocoa技术,两者都实现了观察者模式。

  • 通知

    Cocoa Touch框架中使用NSNotificationCenter和NSNotification对象实现了一对多的发布订阅模型。一个中心对象为所有观察者提供变更通知,主要从广义上关注程序事件
  • 键值观察

    被观察的对象直接向观察者发送通知,绑定与特定对象属性的值。

例子

User.h

//
// User.h
// ObserverDemo
//
// Created by zhanggui on 15/8/6.
// Copyright (c) 2015年 zhanggui. All rights reserved.
// #import <Foundation/Foundation.h> @interface User : NSObject
{
NSString *userName;
NSString *userAge;
NSString *userAddress;
}
@end

User.m

//
// User.m
// ObserverDemo
//
// Created by zhanggui on 15/8/6.
// Copyright (c) 2015年 zhanggui. All rights reserved.
// #import "User.h" @implementation User @end

ViewController.m

//
// ViewController.m
// ObserverDemo
//
// Created by zhanggui on 15/8/6.
// Copyright (c) 2015年 zhanggui. All rights reserved.
// #import "ViewController.h"
#import "User.h"
@interface ViewController ()
{
User *user1;
}
@end @implementation ViewController - (void)viewDidLoad {
[super viewDidLoad];
user1 = [User new];
[user1 setValue:@"zhangsan" forKey:@"userName"];
//KVO
[user1 addObserver:self forKeyPath:@"userName" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:@"I want to update name"];
_nameLabel.text = [user1 valueForKey:@"userName"]; //Notification
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(changeColor:) name:@"changeColor" object:nil];
}
-(void)dealloc {
[user1 removeObserver:self forKeyPath:@"userName"];
}
#pragma mark - NotificationAction
-(void)changeColor:(NSNotification *)notification
{
if ([notification.object isKindOfClass:[UIColor class]]) {
self.view.backgroundColor = (UIColor *)notification.object;
}
NSLog(@"我收到通知了");
} #pragma mark - ButtonAction
- (IBAction)buttonAction:(id)sender {
[user1 setValue:@"zhangqiang" forKey:@"userName"];
} #pragma mark - ObserverMehtod
-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if ([keyPath isEqualToString:@"userName"]) {
_nameLabel.text = [user1 valueForKey:@"userName"];
}
}
@end

SecondViewController.m

//
// SecondViewController.m
// ObserverDemo
//
// Created by zhanggui on 15/8/6.
// Copyright (c) 2015年 zhanggui. All rights reserved.
// #import "SecondViewController.h" @interface SecondViewController () @end @implementation SecondViewController - (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
} - (IBAction)changeColorAction:(id)sender {
[[NSNotificationCenter defaultCenter] postNotificationName:@"changeColor" object:[UIColor redColor]];
}
@end

上述例子中分别使用了KVO和NSNotificationCenter来体现观察者模式。其中:

 [user1 addObserver:self forKeyPath:@"userName" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:@"I want to update name"];

我们给user1添加观察者self,也就是ViewController。让它去观察user的userName属性,当有更新的时候就会调用:

-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if ([keyPath isEqualToString:@"userName"]) {
_nameLabel.text = [user1 valueForKey:@"userName"];
}
}

在这里来处理显示内容的更新。

还有就是通过SecondViewController中点击一个按钮去改变ViewController的背景色,具体请看代码。

附:

iOS设计模式之观察者模式的更多相关文章

  1. 【转】iOS设计模式之观察者模式

    参考:http://blog.csdn.net/xdrt81y/article/details/24039163 或者 http://blog.jobbole.com/55505/

  2. iOS设计模式(01):观察者

    iOS设计模式(01):观察者 iOS-Observer-Pattern 什么是观察者模式 什么是观察者模式?你曾经订阅过报纸吗?在订阅报纸的时候,你不用去任何地方,只需要将你的个人地址信息以及订阅信 ...

  3. IOS设计模式浅析之单例模式(Singleton)

    说在前面 进入正式的设计模式交流之前,扯点闲话.我们在项目开发的过程中,经常会不经意的使用一些常见的设计模式,如单例模式.工厂方法模式.观察者模式等,以前做.NET开发的时候,认真拜读了一下程杰老师的 ...

  4. iOS书摘之Objective-C编程之道 iOS设计模式解析

    来自<Objective-C编程之道iOS设计模式解析>一书的摘要总结 一.Prototype 原型模式 定义:使用原型实例指定创建对象的种类,并通过复制这个原型创建新的对象.(<设 ...

  5. iOS 设计模式

    很赞的总结 iOS Design Patterns 中文版 IOS设计模式之一(MVC模式,单例模式) IOS设计模式之二(门面模式,装饰器模式) IOS设计模式之三(适配器模式,观察者模式) IOS ...

  6. iOS设计模式 - (1)概述

    近期可自由安排的时间比較多, iOS应用方面, 没什么好点子, 就先放下, 不写了.花点时间学学设计模式. 之后将会写一系列博文, 记录设计模式学习过程. 当然, 由于我自己是搞iOS的, 所以之后设 ...

  7. IOS设计模式之一(MVC模式,单例模式)

    iOS 设计模式-你可能已经听说过这个词,但是你真正理解它意味着什么吗?虽然大多数的开发者可能都会认为设计模式是非常重要的,然而关于设计模式这一主题的文章却不多,并且有时候我们开发者在写代码的时候也不 ...

  8. iOS 设计模式之工厂模式

    iOS 设计模式之工厂模式 分类: 设计模式2014-02-10 18:05 11020人阅读 评论(2) 收藏 举报 ios设计模式 工厂模式我的理解是:他就是为了创建对象的 创建对象的时候,我们一 ...

  9. iOS设计模式之生成器

    iOS设计模式之生成器 1.生成器模式的定义 (1): 将一个复杂的对象的构件与它的表示分离,使得相同的构建过程能够创建不同的表示 (2): 生成器模式除了客户之外还包括一个Director(指导者) ...

随机推荐

  1. java攻城狮之路(Android篇)--BroadcastReceiver&Service

    四大组件:activity 显示. contentProvider 对外暴露自己的数据给其他的应用程序.BroadcastReceiver 广播接收者,必须指定要接收的广播类型.必须明确的指定acti ...

  2. [原创]与来自facebook的朋友交流

    与来自facebook的朋友交流 老板的儿子在facebook工作,现在正好有个假期回来,老总让我们部门与之进行一次交流.其实主要是他讲一下那边情况,然后我们准备些问题,多扩展一下我们见识. 流程 交 ...

  3. Entity Framework访问MySQL数据库的存储过程并获取返回值

      一.创建MySql存储过程 1, CREATE PROCEDURE `InsertAlarmInfo`(in businessindex int, in providerindex int, in ...

  4. 【翻译】C# Tips & Tricks: Weak References - When and How to Use Them

    原文:C# Tips & Tricks: Weak References - When and How to Use Them Sometimes you have an object whi ...

  5. 疯狂的ASP.NET系列-第一篇:啥是ASP.NET

    最近想学下ASP.NET,于是在网店上看到一本书叫做ASP.NET高级程序设计,老婆在旁边问了句:“这个不是DSP(数字信号处理,大学读的电子,所以这个比较熟),是ASP啊,什么是ASP啊?”.我想了 ...

  6. Mysql学习笔记(九)索引查询优化

    PS:上网再次看了一下数据库关于索引的一些细节...感觉自己学的东西有点少...又再次的啃了啃索引.... 学习内容: 索引查询优化... 上一章说道的索引还不是特别的详细,再补充一些具体的细节... ...

  7. Android中的依赖问题(五种依赖、eclipse、AS、添加第三方库、jar)

    这篇文章的主题是: 依赖是什么 eclipse中的依赖 AS中的依赖(有一篇详细的文章讲得非常好,这里就不再写了http://blog.csdn.net/yy1300326388/article/de ...

  8. sprint3(第八天)

    昨天忘了发博客,最近在整合前台和后台的内容,在sprint结束前应该能整合好,然后实现前后台的联系,实现点餐功能. 最近要准备大作业也要复习四六级考试,所以花在项目的时间比较少了,请老师谅解. 燃尽图

  9. IOS 之 PJSIP 笔记(二) iPJSUA 的简单使用

    上一篇在编译完之后,就很不负责的结束了,本篇就对 PJSIP 库中提供的一个示例 iPJSUA 的使用,做一个简单的介绍.也能解除很多人对官方文档的一个困扰,起码我是被困扰过了. 首先,要确保你的 P ...

  10. css中position与z-index

    position属性 在css中,position属性用来控制元素的位置信息,其取值共有4种,即static.relative.absolute.fixed. 静态定位(static) 若没有指定po ...