设计模式:观察者模式

背景

需求:将气象站的数据显示在布告板上。如下图所示:

(1)气象站:由WeatherStation类表示,有3个属性(温度、湿度、气压),当气象站的数据有变化时,会调用measurementsDidChanged方法。

(2)布告板:由CurrentDisplay类表示,调用update方法来刷新布告板的数据。

第1版实现

在WeatherStation类中新增CurrentDisplay属性display,当气象数据变化时,在measurementsDidChanged方法中调用display的update方法。OC实现代码如下:

// 气象站数据变化会调用该方法
- (void)measurementsDidChanged {
    [self.display updateTemperature:self.temperature humidity:self.humidity pressure:self.pressure];
}

问题1:WeatherStation和CurrentDisplay类耦合,当需要新增或删除布告板时,都得修改measurementsDidChanged方法,违背开闭原则。但这个问题似乎影响不大,因为只需要修改measurementsDidChanged方法中的逻辑,工作量不大。

再来思考另一个问题:如果布告板上需要新增展示风力风向,则不仅需要修改CurrentDisplay类的update方法(新增参数),还需要修改measurementsDidChanged方法中的逻辑。耦合就意味着修改一个类可能影响另外的类。

分析需求可知,当气象数据变化时,需要通知布告板显示最新的数据。那该如何通知呢?观察者模式就是用来解决一个对象状态改变给其他对象通知的问题。更一般的情况,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

第2版实现

 新增2个接口:Subject(主题)和Observer(观察者)

然后由WeatherStation类实现Subject接口,CurrentDisplay类实现Observer接口

/// 注册观察者
/// @param observer 观察者
- (void)addObserver:(id<Observer>)observer {
    if (observer) {
        [self.observers addObject:observer];
    }
}

/// 移除观察者
/// @param observer 观察者
- (void)removeObserver:(id<Observer>)observer {
    if (observer) {
        [self.observers removeObject:observer];
    }
}

/// 通知所有观察者
- (void)notifyObservers {
    for (id<Observer> observer in self.observers) {
        if ([observer respondsToSelector:@selector(update)]) {
            [observer update];
        }
    }
}

当气象数据变化时,调用notifyObservers方法通知观察者update数据

- (void)update {
    if ([self.subject isKindOfClass:[WeatherStation class]]) {
        WeatherStation *ws = (WeatherStation *)self.subject;
        [self updateTemperature:ws.temperature humidity:ws.humidity pressure:ws.pressure];
    }
}

- (void)updateTemperature:(int)temperature humidity:(int)humidity pressure:(int)pressure {
    NSLog(@"当前天气:温度:%d℃,湿度:%d%%,气压:%dmb", temperature, humidity, pressure);
}

使用观察者模式之后,虽然WeatherStation类不在依赖CurrentDisplay类,但是CurrentDisplay类仍然需要依赖WeatherStation类,这样做是为了能从WeatherStation类中获取最新的气象数据。这就是标准的观察者模式。

观察者模式

意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。 

应用场景:一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。

总结

观察者模式解决了一个对象状态改变给其他对象通知的问题。在iOS中可以使用NSNotificationCenter很好的实现这一类型的需求,并且做到WeatherStation和CurrentDisplay完全解耦,但它使用的是中介者模式,后续再做详细介绍。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值