观察者模式(Observer)
多个观察者关注同一个目标,当目标发生改变时,观察者们可以收到消息。
(立刻更新消息,或者想知道的时候更新消息。)
实现:
1、自定义观察者:观察者与目标有一致的状态属性,目标持有观察者的引用。
2、jdk自带的:
java.util.Observable 类,实现它的类即可被观察(目标类)。
核心方法:
setChanged();//通知观察者目标的信息已经修改 notifyObservers(state);//传入状态,修改观察者们通过update方法可获得state,即可修改状态
java.util.Observer接口,实现它的类需要重写update 方法,昨晚观测者。
void update(Observable var1, Object var2);//var1 为目标对象,var为传过来的状态。
自定义观察者:
1、观察者接口:有观察者的统一方法:更新
public interface Observer { void update(Subject subject);//更新数据 }
2、具体观察者:
public class MyObserver implements Observer{ private int myState;//统一状态变量 @Override public void update(Subject s) { //改变为指定的状态 myState = ((ConcreteSubject)s).getState(); } public int getMyState() { return myState; } public void setMyState(int myState) { this.myState = myState; } }
3、目标父类:统一需要实现的方法。
public class Subject { //观察者们 protected List<Observer> list = new ArrayList<>(); //注册一个观察者 public void registerObserver(Observer o){ list.add(o); } //移除一个观察者 public void removeObserver(Observer o){ list.remove(o); } //通知观察者们进行更新 public void notifyAllObersvers(){ for(Observer o:list){ o.update(this);//更新为此时状态 } } }
4、目标:此处设计为目标状态一改变,就更新观察者们的状态。
public class ConcreteSubject extends Subject{ private int state;//状态变量 public int getState() { return state; } public void setState(int state) { this.state = state; //状态一改变,就通知观察者们更新状态 this.notifyAllObersvers(); } }
测试:
public class Client { public static void main(String[] args) { //创建目标 ConcreteSubject cs = new ConcreteSubject(); //创建三个观察者 MyObserver m1 = new MyObserver(); MyObserver m2 = new MyObserver(); MyObserver m3 = new MyObserver(); //注册观察者 cs.registerObserver(m1); cs.registerObserver(m2); cs.registerObserver(m3); System.out.println("m1状态为:"+m1.getMyState()); System.out.println("m2状态为:"+m2.getMyState()); System.out.println("m3状态为:"+m3.getMyState()); //移除观察者3 cs.removeObserver(m3); //改变状态 cs.setState(123); System.out.println("m1状态为:"+m1.getMyState()); System.out.println("m2状态为:"+m2.getMyState()); System.out.println("m3状态为:"+m3.getMyState()); } }
测试结果:
使用jdk提供的目标父类 Observable 及观察者接口 Observer 实现
1、创建目标:
public class ConcreteSubject extends Observable { private int state;//统一的状态 public void setState(int state) { this.state = state; setChanged();//目标的信息已经修改 notifyObservers(state);//通知观察者们 } public int getState() { return state; } }
2、确定观察者模式:状态一变我就更新
public class MyObserver implements Observer { private int myState;//统一的状态类型 @Override public void update(Observable observable, Object o) { //状态更新 //方式1: myState = (int)o; //方式2: //myState = ((ConcreteSubject)observable).getState(); } public int getMyState() { return myState; } public void setMyState(int myState) { this.myState = myState; } }
3、测试:
public class Client { public static void main(String[] args) { //创建目标 ConcreteSubject cs = new ConcreteSubject(); //创建观察者 MyObserver m1 = new MyObserver(); MyObserver m2 = new MyObserver(); MyObserver m3 = new MyObserver(); //注册观察者 cs.addObserver(m1); cs.addObserver(m2); cs.addObserver(m3); //查看状态 System.out.println("m1状态为:"+m1.getMyState()); System.out.println("m2状态为:"+m2.getMyState()); System.out.println("m3状态为:"+m3.getMyState()); //移除观察者2 cs.deleteObserver(m2); //改变目标状态 cs.setState(199); //查看状态 System.out.println("m1状态为:"+m1.getMyState()); System.out.println("m2状态为:"+m2.getMyState()); System.out.println("m3状态为:"+m3.getMyState()); } }
测试结果:
不过,在jdk 9 中这种方式被弃用了。