观察者模式:设计模式系列(七)
观察者模式(Observer Pattern):是一种由多同本质对象与另一种目标对象构建而成,当目标对象发生改变时,多种同本质对象会被通知及作出一系列动作的设计模式,归类为行为型模式。
这一模式的解读分为以下几个方面:
- 有很多实例对象具有同一种目的,所以可以从中抽象出相关的本质。
- 目标对象不定时会发生变化,并且对象数量不唯一,所以也可以从中抽象出相关的本质。
- 只要目标对象一变化,关注它的很多对象会执行相关的方法。
使用观察者模式的思考过程如下:
- 有一些实例对象对于程序运行方式是关键,如果它有变化,那么处理的算法就需要跟着变化。
- 需要时刻盯着这些会不定时变化的关键实例对象,防止处理方式不对导致产生问题。
- 这些关键实例对象一变化就要告诉别人我有变化,而盯着变化的人则要。
那么再明确一下结构,观察者模式结构包含观察者实现类、观察者抽象出来的接口或协议、目标实现类、目标抽象出来的接口或协议。
观察者模式示例代码如下(Swift语言):
protocol ObjectBluePrint{
func registerObserver(observer:ObserverBluePrint);
func unregisterObserver(observer:ObserverBluePrint);
func change();
func notify();
}
class Object:ObjectBluePrint{
private var observer = [ObserverBluePrint]();
func registerObserver(observer:ObserverBluePrint) {
self.observer.append(observer);
print("Registering Observer... count:\(self.observer.count)");
}
func unregisterObserver(observer: ObserverBluePrint) {
for(var i = 0;i < self.observer.count;i++){
if(self.observer[i].getObserverID() == observer.getObserverID()){
self.observer.removeAtIndex(i);
}
}
print("Unregistering Observer... count:\(self.observer.count)");
}
func change() {
print("I am Object,and I have already done something");
self.notify();
}
func notify() {
print("Now I am going to notify Observer");
for(var i = 0;i < self.observer.count;i++){
observer[i].update();
}
}
}
protocol ObserverBluePrint{
func getObserverID()->Int;
func setObserverID(id:Int);
func update();
func show();
}
class Observer:ObserverBluePrint{
var id:Int?;
func getObserverID()->Int {
return self.id!;
}
func setObserverID(id:Int) {
self.id = id;
}
func update(){
print("I am Observer \(self.id!),I have been notified");
self.show();
}
func show(){
print("Observer \(self.id!) can do something for the changed of Object");
}
}
var object:ObjectBluePrint = Object();
var observer1:ObserverBluePrint = Observer();
observer1.setObserverID(1);
object.registerObserver(observer1);
var observer2:ObserverBluePrint = Observer();
observer2.setObserverID(2);
object.registerObserver(observer2);
object.change();
object.unregisterObserver(observer1);
object.change();
代码分析:这段示例代码写得有点复杂,主要是为了突出这个模式的特点。首先创建ObjectBluePrint
的实例对象object
,这里这么做是因为ObjectBluePrint
是抽象出来的协议,对于多种类的Object
实例类可以方便遵循,后续可以再扩展。在Object
实现类的对象中需要注册一些观察者ObserverBluePrint
,这样对于需要通知的目标才会清晰。然后当Object
出现啦变化,即调用了change
方法,那么该方法就会继续调用notify
方法,进而逐个让每一个观察者执行update
,而show
则可以理解为Observer
在知道观察目标出现变化之后进行的一些处理动作。(其实Object
实现类还可以把自己结构往上提升一级,命名为ObjectCenter
,专门用来处理Observer
和下级Object
的添加和删除,这样的扩展可以自己尝试一下)。以上代码输出结果如下:
Registering Observer... count:1
Registering Observer... count:2
I am Object,and I have already done something
Now I am going to notify Observer
I am Observer 1,I have been notified
Observer 1 can do something for the changed of Object
I am Observer 2,I have been notified
Observer 2 can do something for the changed of Object
Unregistering Observer... count:1
I am Object,and I have already done something
Now I am going to notify Observer
I am Observer 2,I have been notified
Observer 2 can do something for the changed of Object
总结:观察者模式也叫发布订阅模式,同时也是常常与MVC架构中的MV联系起来(目的是让C减肥),此模式需要记着,直接联想微博关注的人从发消息到你看见的过程大概就能理解,首先是你关注了那个人,那个人发了消息,就会推送到你的页面,你就可以看到,并且可以点赞回复转发什么的,注意的是你不是唯一一个盯着目标的,而且你盯着的目标也不是唯一的,这是一个多对多的关系。多点思考生活中各种事物的联系,是设计模式的一种学习演变过程,因为技术是来源于生活也反馈于生活的。