阅读 246

技术问答-24 如何实现观察者模式

一、Java实现观察者模式 用java提供的Observable Observer:

package com;import java.util.Observable;import java.util.Observer;/**
 * 被通知的对象
 * @author Administrator
 *
 */public class User implements Observer {private String name;public User(String name) {this.name = name;}public void update(Observable o, Object arg) {
System.out.println("抢票用户"+name + arg+"有票了:");}}


package com;import java.util.Observable;/**
 * 被观察者
 * @author Administrator
 *
 */public class OfficialAccount extends Observable {public void publishNewInfo(String info) {setChanged();notifyObservers(info);}}


package com;/**
 * 测试
 * @author Administrator
 *
 */public class Test {public static void main(String[] args) {// 被观察的角色
OfficialAccount officialAccount = new OfficialAccount();// 观察者
User userliu = new User("小刘");
User userli = new User("小李");
User userbai = new User("小白");// 将观察者注册到可观察对象的观察者列表中
officialAccount.addObserver(userliu);
officialAccount.addObserver(userli);
officialAccount.addObserver(userbai);// 发布消息
officialAccount.publishNewInfo("k123");//小刘抢了k123 不用再抢了
officialAccount.deleteObserver(userliu);//
officialAccount.publishNewInfo("D345");}}


二、观察者模式解释



  • 观察者模式:有时又被称为发布(publish )-订阅(Subscribe)模式、模型-视图(View)模式、源-收听者(Listener)模式或从属者模式,是软件设计模式的一种

  • 在此种模式中,一个目标物件管理所有相依于它的观察者物件(说白了就是我被观察了 我还得管着观察我的人 真心累!),

  • 被观察者本身的状态改变时主动发出通知(你望远镜看着我 我动了一下 我还要打电话告诉你 我动了! )。

  • 被观察者通常通过调用各观察者所提供的方法来实现(我 需要打你电话 还得是你的电话号码)。

  • 此种模式通常被用来实现事件处理系统



三、 自己实现观察者模式

我的总结:观察者模式就是 被观察的人把所有观察他的人存起来 一旦自己状态变了之后 就挨个通知观察他的人
自己写一个的话 就是
一个被观察者类 (1) 存储所有他的观察者 (2)状态改变方法 (3) 通知观察者方法
一个观察者类 (1) 有一个方法 给被观察者调用

package com;/**
 * 观察者
 * 
 * @author Administrator
 *
 */public class Guancha {public Guancha(String name) {this.name = name;}private String name;/**
 * 这是一个被调用的方法 当被观察者状态变化之后 就会调用所有他的观察者的这个方法
 */public void update(String str) {
System.out.println(name + ":收到被观察者的通知!   " + "被观察者状态:" + str);}}


package com;import java.util.ArrayList;import java.util.List;/**
 * 被观察者
 * 
 * @author Administrator
 *
 */public class BeiGuancha {// 被观察者的状态private String state;// 存储他所有的观察者
List<Guancha> guanchazhes;public BeiGuancha() {
guanchazhes = new ArrayList<Guancha>();}// 添加观察者public void addGuancha(Guancha g) {
guanchazhes.add(g);}// 通知所有观察者public void notifyAllGuancha() {for (Guancha g : guanchazhes) {
g.update(state);}}public String getState() {return state;}public void setState(String state) {this.state = state;}}


package com;/**
 * 测试
 * 
 * @author Administrator
 *
 */public class Test {public static void main(String[] args) {// 新建观察者
Guancha g1 = new Guancha("打不死小强");
Guancha g2 = new Guancha("没对象小明");// 新建被观察者 添加他的观察者
BeiGuancha bgc = new BeiGuancha();
bgc.addGuancha(g1);
bgc.addGuancha(g2);// 修改被观察者状态
bgc.setState("修改009");// 通知观察者 状态变了
bgc.notifyAllGuancha();}}




四、用事件委托实现观察者模式

我理解的所谓的事件委托实现 就是不让被观察者直接接触观察者(怕打架??)
而是通过一个中间人(Event) 如果被观察者需要通知观察者的话 就告诉Event 然后Event在去通知观察者 这里会用到反射

为什么会用到反射呢 Event存储了观察者对象 和 方法名 到使用的时候 是动态调用的~~

package com;/**
 * 观察者
 * 
 * @author Administrator
 *
 */public class Guancha {public Guancha(String name) {this.name = name;}private String name;/**
 * 这是一个被调用的方法 当被观察者状态变化之后 就会调用所有他的观察者的这个方法
 */public void update(String str) {
System.out.println(name + ":收到被观察者的通知!   " + "被观察者状态:" + str);}}


package com;import java.lang.reflect.Method;/**
 * Event 他就是把观察者跟被观察者隔离了  也就相当于是代理
 * @author Administrator
 *
 */public class Event {// 观察者private Object object;// 方法名private String methodName;// 方法参数 我觉得 这个应该是在被观察者调用的时候才设置值的(也就是说Event的invoke方法传进来的参数)private Object[] params;// 方法参数类型private Class[] paramTypes;public Event(Object object, String methodName, Class... paramTypes) {this.object = object;this.methodName = methodName;this.paramTypes = paramTypes;}/*
 * 执行该对象的该方法
 */public void invoke(Object... args) {try {// 设置参数this.params = args;
Method method = object.getClass().getMethod(methodName, paramTypes);if (null == method) {return;}
method.invoke(object, params);} catch (Exception e) {
e.printStackTrace();}}}


package com;import java.util.ArrayList;import java.util.List;/**
 * 被观察者
 * 
 * @author Administrator
 *
 */public class BeiGuancha {// 被观察者的状态private String state;// 存储他所有的观察者
List<Event> events;public BeiGuancha() {
events = new ArrayList<Event>();}// 添加观察者public void addGuancha(Event g) {
events.add(g);}// 通知所有观察者public void notifyAllGuancha() {for (Event e : events) {
e.invoke(state);}}public String getState() {return state;}public void setState(String state) {this.state = state;}}


package com;/**
 * 测试
 * 
 * @author Administrator
 *
 */public class Test {public static void main(String[] args) {// 新建观察者
Guancha g1 = new Guancha("打不死小强");
Guancha g2 = new Guancha("没对象小明");// 新建被观察者 添加他的观察者
BeiGuancha bgc = new BeiGuancha();
bgc.addGuancha(new Event(g1, "update", new Class[]{String.class}));
bgc.addGuancha(new Event(g2, "update", new Class[]{String.class}));// 修改被观察者状态
bgc.setState("修改009");// 通知观察者 状态变了
bgc.notifyAllGuancha();}}


文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐