Java设计模式--观察者模式

来源:互联网 发布:百度搜索排名算法 编辑:程序博客网 时间:2024/06/05 21:04

应用场合:

主题-观察者,当主题的状态改变时,调用notify方法通知所有的观察者作出相应的处理(即调用观察者的updae方法)。

是一种一对多的关系,主题只有一个,这个主题有一个观察者队列(observerList<Observer>)。

主题和观察者都是接口,虽然说观察者模式解耦了观察者和主题,但是对于这两个接口来说,他们是相互依赖的。

观察者模式接口关系

主题

  • 这个接口要提供1.添加观察者的方法;2.删除观察者的方法;3.通知观察的方法。
  • 其实现类中,有一个List类型的成员变量用来存储观察者。在通知观察的方法中,对List进行变量,调用观察者的update方法。

观察者

  • 观察者接口中要有一个update方法,当主题通知观察者时,会调用这个update方法来将业务状态传递给观察者。

每声明一个观察者时,通过构造函数的方式需要绑定一个主题,此时将这个观察者添加到某个主题的队列中。当观察者想要退出主题时,需要调用主题的方法,主题从自己的队列中删除这个观察者。

Subject sub=new Sub();Observer obj=new Observer(sub); //绑定主题sub.notify(); //遍历观察者,调用观察者的update方法sub.removeObserver(obj); //主题将观察者从自己的观察者队列中移除

小实例

主题接口

主题接口中提供了三个基础方法:addObserver()用于给主题添加Observer,removeObserver()用于将Observer移除主题的监听队列,notifying()方法用于遍历、通知观察者,即遍历调用Observer的update()方法。

package com.model;public interface Subject{    void addObserver(Observer obj);    void removeObserver(Observer obj);    void notifying(Message message);}

观察者接口

Observer接口中主要是定义了update()方法,主题在通知观察者时,就会调用这个方法

package com.model;public interface Observer{    String getObserverName();    void update(Message message);}

辅助的一个业务类接口

一个辅助类,用于Subject和Observer间传递消息内容

package com.model;public interface Message{    String getMessage();}

主题的实现类

package com.model.impl;import java.util.ArrayList;import java.util.Iterator;import com.model.Message;import com.model.Observer;import com.model.Subject;public class Event implements Subject{    ArrayList<Observer> observerList;    public Event() {        super();        this.observerList = new ArrayList<Observer>();    }    @Override    public void addObserver(Observer obj) {        this.observerList.add(obj);    }    @Override    public void removeObserver(Observer obj) {        this.observerList.remove(obj);    }    public String getObserverList() {        String list="";        for(Iterator<Observer> iter=observerList.iterator();iter.hasNext();) {            list+=iter.next().getObserverName();        }        return list;    }    @Override    public void notifying(Message message) {        for (Iterator iterator = observerList.iterator(); iterator.hasNext();) {            Observer observer = (Observer) iterator.next();            observer.update(message);        }    }}

观察者实现类

- package com.model.impl;import com.model.Message;import com.model.Observer;import com.model.Subject;public class Listener implements Observer{    private String message;    private String listenerName;    Subject sub;    public Listener(Subject sub)    {        this.sub = sub;        sub.addObserver(this);        this.message = "";        this.listenerName = "";    }    @Override    public void update(Message message)    {        this.setMessage(message.getMessage());        System.out.println(this.getRuleMessage());    }    public void setMessage(String message)    {        this.message = message;    }    String getMessage()    {        return this.message;    }    String getRuleMessage()    {        String message = this.getListenerName() + "-->" + this.getMessage();        return message;    }    public String getListenerName()    {        return listenerName;    }    public void setListenerName(String listenerName)    {        this.listenerName = listenerName;    }    @Override    public String getObserverName()    {        return this.getListenerName();    }}

业务实现类

- package com.model.impl;import com.model.Message;public class RuleMessage implements Message{    String message;    public RuleMessage(String message)    {        super();        this.message = message;    }    public void setMessage(String message)    {        this.message = message;    }    @Override    public String getMessage()    {        return this.message;    }}

主方法运行类

场景一
首先定义一个Event,此时他的监听队列是空的。
1号观察者Listener 1注册了Event的监听
Event发生变化后通知自己的观察者队列
场景二
2号观察者Listener 2注册了Event的监听
Event发生变化后通知自己的观察者队列
场景三
1号监听者取消监听Event
Event发生变化后通知自己的观察者队列
package com.model.impl;import com.model.Message;import com.model.Subject;public class Main{    public static void main(String[] args)    {        Subject processorRule = new Event();        System.out.println("This rule event's observerList:{" + ((Event) processorRule).getObserverList() + "}");        Listener processorRuleListener = new Listener(processorRule);        processorRuleListener.setListenerName("listener 1");        System.out.println("listener 1 subscribes!");        System.out.println("This rule event's observerList:{" + ((Event) processorRule).getObserverList() + "}");        System.out.println();        Message ruleMsg1 = new RuleMessage("processor rule1 is fired");        System.out.println("fired rule!");        processorRule.notifying(ruleMsg1);        System.out.println();        Listener processorRuleListener2 = new Listener(processorRule);        processorRuleListener2.setListenerName("listener 2");        System.out.println("listener 2 subscribes!");        System.out.println("This rule event's observerList:{" + ((Event) processorRule).getObserverList() + "}");        Message ruleMsg = new RuleMessage("processor rule2 is fired");        System.out.println("fired rule!");        processorRule.notifying(ruleMsg);        System.out.println();        processorRule.removeObserver(processorRuleListener);        System.out.println("listener 1 leaves!");        System.out.println("This rule event's observerList:{" + ((Event) processorRule).getObserverList() + "}");        Message ruleMsg3 = new RuleMessage("processor rule3 is fired");        System.out.println("fired rule!");        processorRule.notifying(ruleMsg3);    }}

业务运行结果:

eclipse运行结果

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 手机迅雷下载版权方不给下载怎么办 白色有彩色花纹的衣服染色了怎么办 载兰花假如下雪和打霜怎么办 皇室战争你的队友离开了对战怎么办 海岛奇兵发现求救信号第三个怎么办 海岛奇兵勋章太多对手太强怎么办 鱼为什么换缸鱼翅黑了怎么办 鱼丸捕鱼大作战换手机了怎么办 2o岁j'j小怎么办 为什么小米5s指纹不能用怎么办 cs录屏软件运行内存太大了怎么办 可是没有他我怎么办啊是什么电视剧 可是没有他我怎么办啊是哪个电视剧 手机太卡了打字打不了了怎么办 梦幻西游的将军令没有电了怎么办 将军令全部的序列号都忘记了怎么办 船员证被公司压着想自己换证怎么办 电子录入系统中无法打开影像怎么办 火车票退票后说银行退款失败怎么办 苹果4s玩游戏闪退怎么办 买了二手房原房主不迁户口怎么办 苹果禁反忘记工id密码了怎么办 玩英雄联盟用腾讯游戏平台卡怎么办 游戏代练接单了没有给我账号怎么办 华为手机进入设置立即闪退怎么办 股东发现公司有做假账现象怎么办 中国在服役期间有纹身被发现怎么办 脚碰了肿了紫了怎么办 外阴出血了怎么办去医院检查没问题 三个半月宝宝体检脚有的紧怎么办 肛门被红枣核刺了一个洞怎么办 肛门里面有棉签上的棉花怎么办 孩子裤子沾屎怎么洗下来怎么办 做完痔疮手术后有点肛门狭窄怎么办 孕妇做b超宝宝不配合怎么办 怀孕产检医生问的尴尬怎么办 带着节育环做的核磁怎么办 便秘洗肠后最一周未排便怎么办 用了开塞露后肚子疼拉不出来怎么办 冰点脱毛当天用沐浴露洗澡了怎么办 自体脂肪填充脸部但发红又痒怎么办