学习观察者模式通用代码:
1,目标对象的定义
2,具体的目标对象定义。
3,再来看看观察者的接口定义
4,看看观察者的具体实现。
先来一个通用的观察者模式实例:
1:定义一个目标对象:包含观察者的添加,删除,以及最重要的通知观察者方法(观察者对象调用自己的方法,方法参数是目标对象)
package com.ObserverPatternCommon; import java.util.ArrayList; import java.util.List; /* * 目标对象,他知道观察它的观察者,并提高注册(添加)和删除观察者的接口 * */ public class Subject { //保存注册的观察者对象 private List<Observer> observers=new ArrayList<Observer>(); //attach detach notifyObserver //添加观察者到集合中 public void attach(Observer observer) { observers.add(observer); } //删除集合中的指定观察者 public void detach(Observer observer) { observers.remove(observer); } //通知所有注册的观察者对象 protected void notifyObservers() { for(Observer observer:observers) { observer.update(this); } } }
2,建立一个具体的目标对象:继承目标对象,并且加上具体目标对象所需的方法:一个目标对象状态的设置和获取,在设置状态的时候,通知观察者。
package com.ObserverPatternCommon; /* * 具体的目标对象,负责把有关状态存入到相应的观察者对象中 * */ public class ConcreteSubject extends Subject { //保存目标对象的状态 private String subjectState; public String getSubjectState() { return subjectState; } public void setSubjectState(String subjectState) { this.subjectState = subjectState; this.notifyObservers();//状态发生改变了,就通知所有的观察者 } }
3,建立观察者接口:
package com.ObserverPatternCommon; /* * 这是一个观察者接口,定义一个更新的接口给哪些在目标发生改变的时候被通知的对象 * */ public interface Observer { //更新的接口,subject表示传入目标对象,方便获取相应的目标对象状态 public void update(Subject subject); }
4,建立具体的观察者接口:因为观察者被目标对象通知的时候,需要观察者调用自己的方法,这里的update。
package com.ObserverPatternCommon; /* * 具体的观察者对象,实现更新的方法,使自身和目标的状态保持一致 * */ public class ConcreteObserver implements Observer { //观察者的状态 private String observerState; /* * 获取目标类的状态,同步到观察者的状态中 * */ @Override public void update(Subject subject) { observerState=((ConcreteSubject)subject).getSubjectState(); } }
上面就是观察者模式通用的结构。
下面以一个具体例子来说:当天气变化的时候,需要通知所有注册的观察者用户(如这里的女朋友和老妈)。
第一步:建立天气目标对象类:包括用户注册方法,用户注销方法,用户通知方法
package WeatherObserverPattern; import java.util.ArrayList; import java.util.List; /* * 目标对象,他知道观察它的观察者,并提高注册(添加)和删除观察者的接口 * */ public class WeatherSubject { //保存注册的观察者对象 private List<Observer> observers=new ArrayList<Observer>(); //attach detach notifyObserver //把订阅天气的人添加到订阅者列表中 public void attach(Observer observer) { observers.add(observer); } //删除集合中的指定订阅天气的人 public void detach(Observer observer) { observers.remove(observer); } //通知所有已经订阅天气的人 protected void notifyObservers() { for(Observer observer:observers) { observer.update(this); } } }
第二步:建立具体的天气目标对象类:包含天气信息方法,当改变天气信息的时候,调用通知用户方法。
package WeatherObserverPattern; /* * 具体的目标对象,负责把有关状态存入到相应的观察者对象中 * */ public class ConcreteWeatherSubject extends WeatherSubject { //获取天气的内容信息 private String weatherContent; public String getWeatherContent() { return weatherContent; } public void setWeatherContent(String weatherContent) { this.weatherContent = weatherContent; //内容有了,说明天气更新了,通知所有的订阅的人 this.notifyObservers(); } }
第三步:定义用户观察者接口:包含一个更新接口
package WeatherObserverPattern; /* * 这是一个观察者接口,定义一个更新的接口给那些在目标发生改变的时候被通知的对象 * */ public interface Observer { //更新的接口,subject表示传入目标对象,方便获取相应的目标对象状态 public void update(WeatherSubject subject); }
第四步:定义用户观察者具体类:包含变量:用户名字,不同用户的提醒信息,以及用来接收天气信息的变量。当天气类通知用户,用户会调用update方法,并且传入
天气类对象,通过天气类对象获取天气信息。
package WeatherObserverPattern; /* * 具体的观察者对象,实现更新的方法,使自身和目标的状态保持一致 * */ public class ConcreteObserver implements Observer { //观察者的名字,是谁收到了这个讯息,黄明的女朋友海事他老妈 private String observerName; //天气的内容情况,这个消息从目标处获取 private String weatherContent; //提醒的内容,黄明的女朋友提醒约会,而他老妈则提醒购物 private String remindThing; public String getObserverName() { return observerName; } public void setObserverName(String observerName) { this.observerName = observerName; } public String getWeatherContent() { return weatherContent; } public void setWeatherContent(String weatherContent) { this.weatherContent = weatherContent; } public String getRemindThing() { return remindThing; } public void setRemindThing(String remindThing) { this.remindThing = remindThing; } /* * 获取目标类的状态,同步到观察者的状态中 * */ @Override public void update(WeatherSubject subject) { weatherContent=((ConcreteWeatherSubject)subject).getWeatherContent(); System.out.println(observerName+"收到了:"+weatherContent+","+remindThing); } }
最后:实现该天气信息通知用户的调用。
package WeatherObserverPattern; public class Client { public static void main(String[] args) { //1,创建目标 ConcreteWeatherSubject weather=new ConcreteWeatherSubject(); //2,创建观察者 ConcreteObserver observerGirl=new ConcreteObserver(); observerGirl.setObserverName("黄明的女朋友"); observerGirl.setRemindThing("是我们的第一次约会,地点街心公园"); ConcreteObserver observerMum=new ConcreteObserver(); observerMum.setObserverName("老妈"); observerMum.setRemindThing("是一个购物的好日子,明天去天虹扫货"); //3,注册观察者 weather.attach(observerGirl); weather.attach(observerMum); //4,目标发布天气 weather.setWeatherContent("明天 天气晴朗,蓝天白云,气温28度"); } }
执行结果:
黄明的女朋友收到了:明天 天气晴朗,蓝天白云,气温28度,是我们的第一次约会,地点街心公园
老妈收到了:明天 天气晴朗,蓝天白云,气温28度,是一个购物的好日子,明天去天虹扫货