public class ImplementsWatched implements Watched{ // 我们用集合来定义,记录有多个观察者同时观察(监听)一个被观察者, // 只有当被观察者发生变化,多个观察者同时都能收到(变化)消息
List<Watcher> list = new ArrayList<Watcher>();// 用集合的(增加)变化去描述被观察者的变化 @Override public void addWatcher(Watcher watcher) { // TODO Auto-generated method stub list.add(watcher); } // 用集合的(删除)变化去描述被观察者的变化 @Override public void removeWatcher(Watcher watcher) { // TODO Auto-generated method stub list.remove(watcher); }
@Override public void notifyWatcher(String str) { // TODO Auto-generated method stub for (Watcher watcher : list) {// 遍历集合 // 当这个集合的元素(对象)发生变化的时候,我们就主动通知观察者发生了变化,及时通知 watcher.updata(str); } }
}
为了更好的表示这种变化,我们用集合来定义。集合自身增删的特点有助于我们描述这种变化,通过设定集合泛型值为一个观察者对象的时候,老司机们就会知道我接下来要干什么了。通过集合自身的增加和移除去描述被观察者的变化,当我增加一个对象,或者移除一个对象,在这之前先去遍历这个集合,我们就可以知道这个对象是否发生了变化,只要发生了变化,我就调用观察者对外提供的方法,去描述被观察者发生了变化。 写到这里,别忘了我们的观察者也等着我们去实现。 //实现观察者接口 //为了方便我们看到结果,我们直接打印被观察者传递过来的结果(变化) public class ImplementsWatcher implements Watcher{ @Override public void updata(String str) { // TODO Auto-generated method stub System.out.println(str); } } 接下来,我们就写一个主方法,来测试观察者和被观察者之间如何产生关系的吧。“` * * @author Administrator * 测试类:观察者模式 */ public class Test { public static void main(String[] args) { // 创建3个观察者对象来同时监听一个被观察者 Watcher watcher = new ImplementsWatcher(); Watcher watcher1 = new ImplementsWatcher(); Watcher watcher2 = new ImplementsWatcher();
// 创建一个被观察者对象 Watched watched = new ImplementsWatched();
// 被观察者状态发生变化,如何理解? // 在被观察者的接口里面,我们写了两个接口方法来定义这种变化,增加和删除的方法,这里用增加的方法,来表示这种变化 watched.addWatcher(watcher); watched.addWatcher(watcher1); watched.addWatcher(watcher2); // removeWatcher 这个函数 大家有兴趣也可以玩下,也会唤醒观察者 // watched.removeWatcher(watcher);
// 当被观察者发生增加或者删除变化的时候,我们就及时通知观察者, // 那么问题来了,如何通知观察者?这个结果该如何传递?这个结果类型有没有限制? // 我们需要让被观察者去告知观察者,我发生了变化,以及提示给观察者的信息,也就是调用被观察者对外暴露的方法,以及输入相应的参数类型即可 watched.notifyWatcher(“小偷要开车了—>55555”);
}}
在这个测试类里面我们首先创建三个观察者对象来同时监听一个被观察者,然后创建一个被观察者对象来实现被监听,代码如上。接下来就是比较难理解的地方了,那么,我观察者如何知道被观察者发生了变化,在图二中,我们讲到,为了将观察者和被观察者两者结合起来,用到了将观察者以参数的形式传递到被观察者暴露的接口方法里面去的,当发生变化的时候,就调用被观察者中的notifyWatcher()这个函数,然后,我们把程序运行一下。结果如下最后,我们从主方法入手,将这个程序理一遍。 1)创建3个观察者对象 2)创建1个被观察者对象 3)在创建观察者对象的时候,我们是为了更好的显示,就直接讲结果打印在输出台上,输出内容是通过函数传递过来的str 4)在创建被观察者对象的时候,我们在里面创建了一个(观察者)集合,在具体接口暴露的方法中,通过添加观察者对象、移除观察者对象、遍历集合,调用观察者接口暴露的方法去表示这种变化 5)在被观察者,我们调用addWatcher()这个函数,描述这种变化 6)被观察者通知观察者发生了变化(str)——-》观察者调用update(str)函数,将被观察者想要表达的信息返回给观察者,然后在调用——-》ImplementsWatcher这个类里面的update()函数,将传过来的str以System.out的形式输出在控制台上面。整个流程就结束了。
文章的最后,我们在梳理一下思路。当被观察者发生变化的时候及时通知观察者(数据类型)我们就可以通过观察者去获得这个变化(数据类型)。代码逻辑基本上写在注释里面了,然后这是《死磕观察者模式》系列的第一篇,第二篇我会采用JAVA语言自带的观察者模式在写一篇。也希望大家多多支持。
