1:定义
定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新
类图:
设计原则
为了交互对象之间的松耦合设计而努力
2:实现观察者
观察者主动推数据:
1):主题接口:拥有注册(增加)、删除观察者的方法(它会拥有观察都集合字段),并当主题状态变化时,调用某个方法,以便通知观察者。
2):观察者接口:当主题变化时,主题会调用观察者对象的方法
3):观察者接口2:这个接口存放所有观察者变化的方法
4):主题类:实现主题接口,构造器中初始化观察者容器,并实现注册,删除方法,实现“通知观察者”方法,当状态改变时,调用观察者接口方法
5):观察者类:实现观察者接口与观察者接口2,持有主题对象,有参构造器(参数是主题对象)中赋值给字段,并调用主题的注册方法注册观者
我的代码:
主题接口
package com.gbz.imp;
/**
* 模拟报社与订阅者
* 主题接口:拥有注册(增加)、删除观察者的方法(它会拥有观察都集合字段),
* 并当主题状态变化时,调用某个方法,以便通知观察者。
*/
public interface Subject {
//我须要订阅
public void add(Observer o);
//我要退订
public void remove(Observer o);
//有新报时发给订阅者
public void call();
}
观察者接口
package com.gbz.imp;
// 观察者接口:当主题变化时,主题会调用观察者对象的方法
public interface Observer {
//有新的报纸
public void update(String militaryNews, String entertainmentNews);
}
package com.gbz.imp;
//观察者接口2:这个接口存放所有观察者变化的方法
public interface Observer2 {
//读出报纸
public void read();
}
主题类:
package com.gbz;
/**
* 报社
* 主题类:实现主题接口,构造器中初始化观察者容器,并实现注册,删除方法,实现“通知观察者”方法,
* 当状态改变时,调用观察者接口方法
*/
import java.util.ArrayList;
import java.util.List;
import com.gbz.imp.Observer;
import com.gbz.imp.Subject;
public class NewspaperOffice implements Subject {
// 报社中的新闻
public String militaryNews;
public String entertainmentNews;
public List<Observer> allObserver = null; // 所有订阅者
public NewspaperOffice() {
allObserver = new ArrayList<Observer>();
}
@Override
// 客户要订新闻
public void add(Observer o) {
allObserver.add(o);
}
@Override
// 客户要退订
public void remove(Observer o) {
allObserver.remove(o);
}
@Override
// 通知订阅者
public void call() {
for (Observer o : allObserver) {
o.update(militaryNews,entertainmentNews);
}
}
// 报社有了新闻
public void setNows(String militaryNews, String entertainmentNews) {
this.militaryNews = militaryNews;
this.entertainmentNews = entertainmentNews;
call();
}
}
观察者1
package com.gbz;
import com.gbz.imp.Observer;
import com.gbz.imp.Observer2;
import com.gbz.imp.Subject;
/**
* 观察者类:实现观察者接口与观察者接口2,持有主题对象,有参构造器(参数是主题对象)
* 中赋值给字段,并调用主题的注册方法注册观者
*
*/
public class MilitaryEnthusiasts implements Observer, Observer2 {
private Subject peoplesDaily; //人民日报
private String militaryNews;
private String entertainmentNews;
public MilitaryEnthusiasts(){}
public MilitaryEnthusiasts(Subject peoplesDaily){
this.peoplesDaily=peoplesDaily;
}
//我要订阅
public void takeNewspaper(){
peoplesDaily.add(this);
}
//我要退订
public void unsubscribe(){
peoplesDaily.remove(this);
}
@Override
//读出新闻
public void read() {
System.out.println("我是军事迷,今天 的军事新闻是:"+militaryNews);
}
@Override
public void update(String militaryNews, String entertainmentNews) {
this.militaryNews = militaryNews;
read();
}
}
观察者2
package com.gbz;
import com.gbz.imp.Observer;
import com.gbz.imp.Observer2;
import com.gbz.imp.Subject;
public class EntertainmentEnthusiasts implements Observer, Observer2 {
private Subject peoplesDaily; // 人民日报
private String militaryNews;
private String entertainmentNews;
public EntertainmentEnthusiasts() {
}
public EntertainmentEnthusiasts(Subject peoplesDaily) {
this.peoplesDaily = peoplesDaily;
peoplesDaily.add(this);
}
@Override
public void read() {
System.out.println("我是娱乐大V,今天 的新闻是:" + entertainmentNews);
}
@Override
public void update(String militaryNews, String entertainmentNews) {
this.entertainmentNews = entertainmentNews;
read();
}
}
main方法
package com.gbz;
public class Mail {
public static void main(String[] args) {
NewspaperOffice peoplesDaily = new NewspaperOffice();
MilitaryEnthusiasts militaryEnthusiasts = new MilitaryEnthusiasts(peoplesDaily);
militaryEnthusiasts.takeNewspaper();
EntertainmentEnthusiasts entertainmentEnthusiasts = new EntertainmentEnthusiasts(peoplesDaily);
peoplesDaily.setNows("中国研制出了新武器", "娱乐圈很疯狂");
militaryEnthusiasts.unsubscribe();//军事迷退订了
peoplesDaily.setNows("。。。。", "。。。。");//新闻更新了
}
}
运行结果
我是军事迷,今天 的军事新闻是:中国研制出了新武器
我是娱乐大V,今天 的新闻是:娱乐圈很疯狂
我是娱乐大V,今天 的新闻是:。。。。
我是娱乐大V,今天 的新闻是:娱乐圈很疯狂
我是娱乐大V,今天 的新闻是:。。。。