概念:
抽象主题(Subject):即被观察者(Observable)。抽象主题把所有的观察者对象的引用存放在一个集合里,每个主题可以有任意数量的观察者。抽象主题提供一个接口,可以增加或者删除观察者对象。
具体主题(ConcreteSubject):即具体被观察者。具体主题将有关状态存入具体的观察对象,在具体主题的内部状态发生变化时,给所有注册过的观察者对象发出通知。
抽象观察者(Observer):抽象观察者是观察者的抽象类,它定义了一个更新接口,使得在主题发出通知的时候更新自己。
具体观察者(ConcreteObserver):实现抽象观察者所定义的更新接口,在主题的状态发生变化时更新自身的状态。
我的理解:
本质上就是通过接口回调某个对象的方法。关键点在于两个对象,对象A持有对象B的引用,即(被观察者)A持有(观察者)B,并且在需要的时候A能够控制B,或者通知B去执行一些方法。
举个栗子:比如上课铃声响起的时候,学生需要回到教室。这里铃声就比作被观察者,学生就是观察者。响铃就代表被观察者发出通知,学生听到了也就是观察到了这个通知,于是发生了回到教室的行为。
什么是接口回调?
接口回调就是指接口的具体实现通过传参的方式,传递给某个对象,可以在不同的地方处理某段方法或者处理某个对象行为 的结果,使得代码变得比较灵活。
比如:
1、回调的接口
2、对象行为
3、测试代码
4、结果
回到正题。
如何实现观察者模式
第一步:我们需要主题,主题就是被观察者,被观察者就是不断在改变自身状态的对象,在程序当中我们经常需要根据某个对象的状态来在不同的地方做相应的操作,比如:
addObsercer()、removeObserver()、notifyObserver()就是Observerable抽象主题类的方法。以下可以看到抽象主题类中有个Observer集合,其作用就是提供一个容器来存放观察者对象,也可以移除。所以继承了这个类就可以对这个集合进行操作,也可以操作集合中的对象的方法。
Observer接口就是抽象观察者了,对象实现了这个接口就相当与是具体观察者。
getMessage()方法是用来被 被观察者 调用的,相当于是观察者收到了通知。
第二步:我们需要观察者,任何需要根据另外一个对象的状态变化而变化的对象,都可以理解为是观察者。
阿珍和田鸡要重当观察者,所以实现了Observer接口,所以都有一个同样的getMessage方法,阿强通过调用阿珍和田鸡的getMessage方法才能让他们两收到通知。
第三步:测试,这里我调用test执行
运行:结果如下
阿强调用gotoPark()方法出门的时候也调用了阿珍和田鸡的getMessage()方法,所以阿珍和田鸡收到了消息,也调用gotoPark出门去公园。
总结:
本质上还是对象A持有另外一个对象B的引用,所以A可以调用B的方法,B对象可以根据传入的参数来做相应的操作。Observer接口和Observerable抽象接口,主要是为了可以让任意对象得到扩展,从而变成观察者或被观察者。
上面的阿强也可以不实现抽象接口,只要在阿强里面添加一个成员变量来表示阿珍,一个成员变量表示田鸡,再对应增加他们的set方法,然后在阿强去公园的时候使用阿珍和田鸡这两个成员变量分别去调用各自的gotoPark方法,也能达到同样的效果。但显然这种方式是比较不灵活的。
by the way:
接口类是能力。
抽象类是本质。