iOS设计模式之观察者模式

简介:

观察者模式

基本理解

  • 观察者模式又叫做发布-订阅(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的背景色,具体请看代码。

附:

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