之前的关于观察者模式的文章,是用自己写的Observable接口和Observer接口,然后进行实现。其实官方的util包下自带有实现观察者模式对应的接口和类,可以简化我们的代码结构。
比如我们可以直接创建一个子类通过继承 util包下的Observable类来成为被观察者,这样就不用自己去写一个接口,然后实现它的方法,或是自己创建一个List来存储所有观察者了。
我们只需要在需要通知观察者时先调用setChanged()来表示自己的数据或状态已经发生了改变,然后在调用notifyObservers()方就可以了。
依旧拿上次的猫叫惊醒主人,吓跑老鼠的场景为例:
先写Cat类
public class Cat extends Observable{ public String message; public void miao(){ this.message="喵~~"; System.out.println("喵~~"); setChanged(); notifyObservers(this.message); }
可见,这次的代码比之前简洁了许多,我们这里要注意的是 ,在调用notifyObservers()方法之前一定要先调用setChanged()方法,用于表示被观察者的状态已经发生了改变,不然观察者们不会进行响应。另外,我们可以注意到,notifyObservers()传入的是this.message,也就是把 "喵~~" 发送给观察者。
再看另一边的观察者们
老鼠类
public class Mouse implements java.util.Observer{ public void run(String message){ System.out.println("我听到了"+message+" 快跑啊!猫来啦!!"); } @Override public void update(java.util.Observable o, Object arg) { run(arg.toString()); }}
老鼠类的update()方法中有两个参数,第一个就是被观察者对象,也就是猫,第二个就是猫的notifyObservers()方法里传入的参数,也就是“喵~~”,如果之前在猫的notifyObservers()方法中什么都不传,那么这里得到的arg就是null。我们在update()方法中直接执行了run()方法,表示老鼠开始逃跑。
来看最后一个 主人类
public class Master implements java.util.Observer{ public void awake(String message){ System.out.println(message.toString()+" 别打扰我睡觉!!"); } @Override public void update(Observable o, Object arg) { awake(arg.toString()); }}
和老鼠类的实现相同,在update()中调用awake()方法表示被吵醒。
场景类
public class Context { public static void main(String[] args) { Cat tom=new Cat(); Master master=new Master(); Mouse jerry=new Mouse(); tom.addObserver(master); tom.addObserver(jerry); tom.miao(); }}
场景类基本没有变化
最终的执行结果如下:
喵~~我听到了喵~~ 快跑啊!猫来啦!!喵~~ 别打扰我睡觉!!
总的来说,使用官方的类和接口后,我们的代码相较之前简洁了许多,如果对观察者模式不够熟悉的,可以先自己去写Observable和Observer接口来实现。而如果已熟练掌握了大概的思想,还是推荐使用官方提供给我们的util。