JDK自带观察者的使用
被观察者
package observerForJDK; import java.util.Observable; /** * 新闻派发器,当有新的新闻时派发给所有的订阅读者(观察者) */ public class NewsDispatcher extends Observable { public void addNews(String news){ this.setChanged(); this.notifyObservers(news); } }
观察者:
package observerForJDK; import java.util.Observable; import java.util.Observer; /** * 读者(观察者) */ public class Reader implements Observer { private String name; public Reader(String name) { this.name = name; } public void update(Observable o, Object arg) { String news = (String)arg; System.out.println(name + "观察到 : " + news); } }
测试:
package observerForJDK; /** * 测试类 */ public class app { public static void main(String[] args) { //体育新闻派发器 NewsDispatcher sportNewsDispatcher = new NewsDispatcher(); //it新闻派发器 NewsDispatcher itNewsDispatcher = new NewsDispatcher(); //观察者r1,r2,r3 Reader r1 = new Reader("r1"); Reader r2 = new Reader("r2"); Reader r3 = new Reader("r3"); //添加观察者 sportNewsDispatcher.addObserver(r1); sportNewsDispatcher.addObserver(r2); itNewsDispatcher.addObserver(r3); //当有新的新闻的时候,通知观察者 sportNewsDispatcher.addNews("中国队突破了历史获得了世界杯冠军!"); itNewsDispatcher.addNews("ibm 收购 sun公司,java开始收费!"); } }
但这种写法有点问题,观察者需要手动一个一个add进去,太麻烦
改进下:被观察者不变
观察者:
package observerForJDK; import java.util.Observable; import java.util.Observer; /** * 读者(观察者) */ public class Reader2 implements Observer { private String name; private Observable observable; public Reader2(Observable observable,String name) { this.observable = observable; this.observable.addObserver(this); this.name = name; } public void update(Observable o, Object arg) { String news = (String)arg; System.out.println(name + "观察到 : " + news); } }
测试类:
package observerForJDK; /** * */ public class app2 { public static void main(String[] args) { //体育新闻派发器 NewsDispatcher sportNewsDispatcher = new NewsDispatcher(); //it新闻派发器 NewsDispatcher itNewsDispatcher = new NewsDispatcher(); //观察者r1,r2,r3 Reader2 r1 = new Reader2(sportNewsDispatcher,"r1"); Reader2 r2 = new Reader2(sportNewsDispatcher,"r2"); Reader2 r3 = new Reader2(itNewsDispatcher,"r3"); //当有新的新闻的时候,通知观察者 sportNewsDispatcher.addNews("中国队突破了历史获得了世界杯冠军!"); itNewsDispatcher.addNews("ibm 收购 sun公司,java开始收费!"); } }
更实用点的例子:小说网站作者和读者之间的订阅
//读者类,要实现观察者接口 public class Reader implements Observer{ private String name; public Reader(String name) { super(); this.name = name; } public String getName() { return name; } //读者可以关注某一位作者,关注则代表把自己加到作者的观察者列表里 public void subscribe(String writerName){ WriterManager.getInstance().getWriter(writerName).addObserver(this); } //读者可以取消关注某一位作者,取消关注则代表把自己从作者的观察者列表里删除 public void unsubscribe(String writerName){ WriterManager.getInstance().getWriter(writerName).deleteObserver(this); } //当关注的作者发表新小说时,会通知读者去看 public void update(Observable o, Object obj) { if (o instanceof Writer) { Writer writer = (Writer) o; System.out.println(name+"知道" + writer.getName() + "发布了新书《" + writer.getLastNovel() + "》,非要去看!"); } } }
作者类:
//作者类,要继承自被观察者类 public class Writer extends Observable{ private String name;//作者的名称 private String lastNovel;//记录作者最新发布的小说 public Writer(String name) { super(); this.name = name; WriterManager.getInstance().add(this); } //作者发布新小说了,要通知所有关注自己的读者 public void addNovel(String novel) { System.out.println(name + "发布了新书《" + novel + "》!"); lastNovel = novel; setChanged(); notifyObservers(); } public String getLastNovel() { return lastNovel; } public String getName() { return name; } }
然后我们还需要一个管理器帮我们管理这些作者。如下。
import java.util.HashMap; import java.util.Map; //管理器,保持一份独有的作者列表 public class WriterManager{ private Map<String, Writer> writerMap = new HashMap<String, Writer>(); //添加作者 public void add(Writer writer){ writerMap.put(writer.getName(), writer); } //根据作者姓名获取作者 public Writer getWriter(String name){ return writerMap.get(name); } //单例 private WriterManager(){} public static WriterManager getInstance(){ return WriterManagerInstance.instance; } private static class WriterManagerInstance{ private static WriterManager instance = new WriterManager(); } }
好了,这下我们的观察者模式就做好了,这个简单的DEMO可以支持读者关注作者,当作者发布新书时,读者会观察到这个事情,会产生相应的动作。下面我们写个客户端调用一下。
//客户端调用 public class Client { public static void main(String[] args) { //假设四个读者,两个作者 Reader r1 = new Reader("谢广坤"); Reader r2 = new Reader("赵四"); Reader r3 = new Reader("七哥"); Reader r4 = new Reader("刘能"); Writer w1 = new Writer("谢大脚"); Writer w2 = new Writer("王小蒙"); //四人关注了谢大脚 r1.subscribe("谢大脚"); r2.subscribe("谢大脚"); r3.subscribe("谢大脚"); r4.subscribe("谢大脚"); //七哥和刘能还关注了王小蒙 r3.subscribe("王小蒙"); r4.subscribe("王小蒙"); //作者发布新书就会通知关注的读者 //谢大脚写了设计模式 w1.addNovel("设计模式"); //王小蒙写了JAVA编程思想 w2.addNovel("JAVA编程思想"); //谢广坤取消关注谢大脚 r1.unsubscribe("谢大脚"); //谢大脚再写书将不会通知谢广坤 w1.addNovel("观察者模式"); } }
参考:http://blog.csdn.net/zuoxiaolong8810/article/details/9081079