参考 Head First (原创、总结)
大家好!我是IT小蔡,最近由于项目不紧张,空闲之余我在阅读<<Head First >>这本书,以后每学习一种设计模式我都会在这里分享给大家,虽然都是很老的知识,但都是我双手打出来的,非常感谢大家前来赐教,希望在以后共同学习,一起进步。
观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都能收到通知并自动更新。(一只穿云箭,千军万马来相见)。
认识观察者模式
1.报社的业务就是出版报纸。
2.向某家报社订阅报纸,只要他们有新报纸出版,就会给你送来,只要你是他们的订户,就会一直收到新报纸。
3.当你不想再看报纸的时候,取消订阅,他们就不会再送新报纸给你了。
4.只要报社还在运营,就会有人(单位)向他们订阅报纸,或者取消订阅。
出版社+订阅者 = 观察者模式
把出版社改为 "主题" Subject,订阅者改为 "观察者" Observer .
现在我们来实现 将天气预报 下发给每一个订阅的 成员(也就是观察者)
1、首先定义两个接口 主题 Subject 和 观察者 Observer
public interface Subject {
public void registerObserver(Observer o);//订阅
public void unRegisterObserver(Observer o);//结束订阅
public void notifyObservers(Object object);//将消息通知每一个订阅者
}
public interface Observer {
public void update(Object o);//接收到订阅的消息
}
2、下面创建一个天气预报 主题
public class WeaterData implements Subject{
private List<Observer> list ;
private static WeaterData instance = null;
private WeaterData(){
this.list = new ArrayList<Observer>();
};
public static WeaterData getIntance(){
if(instance == null){
synchronized (WeaterData.class) {
if(instance == null){
instance = new WeaterData();
}
}
}
return instance;
}
public void registerObserver(Observer observer) {
if(!list.contains(observer)){
list.add(observer);
}
}
public void unRegisterObserver(Observer observer) {
if( observer!= null && list.contains(observer)){
list.remove(observer);
}
}
public void notifyObservers(Object t) {
for (Observer observer : list) {
observer.update(t);
}
}
}
3、我们再创建几个订阅者(观察者)
public class ObserverOne implements Observer{
public ObserverOne(){
WeaterData.getIntance().registerObserver(this);
}
public void update(Object o) {
System.out.println("ObserverOne收到的天气:"+o);
}
}
public class ObserverTwo implements Observer{
public ObserverTwo(){
WeaterData.getIntance().registerObserver(this);
}
public void update(Object o) {
System.out.println("ObserverTwo收到的天气:"+o);
}
}
public class ObserverThree implements Observer{
public ObserverThree(){
WeaterData.getIntance().registerObserver(this);
}
public void update(Object o) {
System.out.println("ObserverThree收到的天气:"+o);
}
}
4、Test类
public class Test {
/**
* @param IT小蔡
*/
public static void main(String[] args) {
ObserverOne observerOne = new ObserverOne();
ObserverTwo observerTwo = new ObserverTwo();
ObserverThree observerThree = new ObserverThree();
// 发布一条天气预报
WeaterData.getIntance().notifyObservers("今天天气很冷,零下10摄氏度!");
}
}
结果
5、如果现在
ObserverOne 想解除订阅
public static void main(String[] args) {
ObserverOne observerOne = new ObserverOne();
ObserverTwo observerTwo = new ObserverTwo();
ObserverThree observerThree = new ObserverThree();
// 发布一条天气预报
WeaterData.getIntance().notifyObservers("今天天气很冷,零下10摄氏度!");
WeaterData.getIntance().unRegisterObserver(observerOne);
System.out.println("*************");
// 再发布一条天气预报
WeaterData.getIntance().notifyObservers("明天天气风和日丽,20摄氏度!");
}
测试结果
使用Java内置的观察者模式
其实Java已经帮我们实现了观察者模式
Java.util 包下 包含最基本的 Obserable类(主题)和Observer接口 ,细心的同学可能发现Obserable是一个类而不是一个接口,更糟的是它甚至没有实现一个接口。这并不是说它没有提供有用的功能,只是想提醒大家注意一些事实。
首先,因为Observable是一个类,你必须设计一个类去继承它,如果想同时具有Observable和另外一个超类的行为,那就陷入两难,毕竟java不支持多继承,这就限制了它的复用潜力,所有有必要的话,还是自己实现Observable
设计原则
1、找出程序中会变化的部分,然后将其和固定不变的方面相分离。
在观察者模式中会改变的是 主题的状态,以及观察者的数目和类型。
2、针对接口编程
主题和观察者都是使用接口,观察者利用主题的接口想主题注册,而主题利用观察者接口通知观察者。
3、多用组合,少用继承
观察者模式利用“组合”将许多观察者组合进主题中,对象之间的这种关系不是通过继承产生的,而是在运行时利用组合的方式产生的。
在Android 里面 广播以及流行的EventBus框架都是采用观察者模式实现的,在我们以后的开发中经常使用。