设计模式-观察者模式

定义:
定义对象之间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。观察者模式的别名包括发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。观察者模式是一种对象行为型模式。

实例:
观察者模式在iOS中体现的技术可分为,KVO&NSNotificaiton, 下面通过KVO实现气象台观测天气变化的简单例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
@interface WeatherStation : NSObject

@property (nonatomic, strong) NSString *status;

@end

@interface WeatherStation ()

@property (nonatomic, strong) NSMutableArray *observerList;

@end

@implementation WeatherStation

- (instancetype)init
{
self = [super init];
if (self)
{
[self addObserver:self forKeyPath:@"state" options:NSKeyValueObservingOptionNew context:nil];
}
return self;
}

- (void)dealloc
{
[self removeObserver:self forKeyPath:@"state"];
}

- (void)observerValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
{
NSString *state = change[@"new"];
[_observerList enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop){
Observer *ob = obj;
[ob observeWeather:state];
}];
}

- (void)registerWithObserver:(Observer *)observer
{
if (!_observerList) _observerList = [NSMutableArray new];
[_observerList addObject:observer];
}
@end
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 观察者
@interface Observer : NSObject

@property (nonatomic, strong) NSString *name;

- (void)observeWeather:(NSString *)state;

@end

@implementation Observer

- (void)observeWeather:(NSString *)state
{
NSLog(@"%@ observer weather changed: %@", _name, weather);
}

@end
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
WeatherStation *station = [WeatherStation new];
Observer *farmer = [Observer new];
Observer *student = [Observer new];
farmer.name = @"farmer";
student.name = @"student";

[station registerWithObserver:farmer];
[station registerWithObserver:student];

station.state = @"rainy";
station.state = @"sunny";

// out
farmer observe weather changed: rainy
student observe weather changed: rainy
farmer observe weather changed: sunny
student observe weather changed: sunny

对应的类图:

优点:

  • 观察者模式可以实现表示层和数据逻辑层的分离,定义了稳定的消息更新传递机制,并抽象了更新接口,使得可以有各种各样不同的表示层充当具体观察者角色。
  • 观察者模式在观察目标和观察者之间建立一个抽象的耦合。观察目标只需要维持一个抽象观察者的集合,无须了解其具体观察者。由于观察目标和观察者没有紧密地耦合在一起,因此它们可以属于不同的抽象化层次。
  • 观察者模式支持广播通信,观察目标会向所有已注册的观察者对象发送通知,简化了一对多系统设计的难度。
  • 观察者模式满足“开闭原则”的要求,增加新的具体观察者无须修改原有系统代码,在具体观察者与观察目标之间不存在关联关系的情况下,增加新的观察目标也很方便。

缺点:

  • 如果一个观察目标对象有很多直接和间接观察者,将所有的观察者都通知到会花费很多时间。
  • 观察者模式不能检测状态改变的过程,只能监听状态改变的结果