博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
设计模式——观察者模式
阅读量:4149 次
发布时间:2019-05-25

本文共 4233 字,大约阅读时间需要 14 分钟。

   观察者模式主要是建立对象之间的一对多关系,当其中一方发生变化时,通知多个对应的对象,而具体什么时候去通知,这个就由具体的子类来实现。

   下图当中给出的是观察者模式之间的结构关系图

Subject

    被观察的对象的抽象接口,其中包括需要通知观察者的集合,同时也提供了,添加观察者和移除观察者方法,以及通知所有的观察者的方法。

ConcreteSubject

   具体的被观察者对象,当具体的被观察者发生某些变化的时候,调用通知所有观察者,同时也对其实现的接口的方法进行了实现

Observer

    观察者对象接口,观察者当中提供了一个更新接口,即通知消息接口,当被观察者需要通知所有的观察者对象时,会调用该接口,并将具体的被观察者对象传递进

ConcreteObserver

    具体的观察者对象,其中实现了更新状态的接口,将被观察者的状态更新至观察者当中。

/** * 目标对象,作为被观察者 */public class Subject {    /**     * 用来保存注册的观察者对象,这里并未考虑线程安全的问题     */    private List
readers = new ArrayList
(); public void attach(Observer reader) { readers.add(reader); } public void detach(Observer reader) { readers.remove(reader); } protected void notifyObservers() { for(Observer reader : readers){ reader.update(this); } }}
public class ConcreteSubject extends Subject{    /**     * 变更内容     */    private String content;    /**     *      * 返回变更的内容     */    public String getContent() {       return content;    }    /**     * 设置变更内容,同时当变更内容发生变化,就通知所有观察者     * @param content 报纸的具体内容     */    public void setContent(String content) {       this.content = content;              notifyObservers();    }}

对于观察者接口

/** * 观察者 */public interface Observer {    /**     * 被通知的方法     * @param subject 具体的目标对象,可以获取被观察者当中的变更内容然后进行通知     */    public void update(Subject subject);}

具体的观察者

public class ConcreteObserver implements Observer{    /**     * 观察者的名字     */    private String name;    public void update(Subject subject) {       //这是采用拉的方式       System.out.println(name+"收到消息啦,内容是==="+((ConcreteSubject)subject).getContent());    }    public String getName() {       return name;    }    public void setName(String name) {       this.name = name;    }}

测试类

public class Client {    public static void main(String[] args) {       //创建被观察者       ConcreteSubject subject = new ConcreteSubject();       //创建阅读者,也就是观察者       ConcreteObserver observer1 = new ConcreteObserver();       observer1.setName("张三");            ConcreteObserver observer2 = new ConcreteObserver();       observer2.setName("李四");            ConcreteObserver observer3 = new ConcreteObserver();       observer3.setName("王五");            //注册阅读者       subject.attach(observer1);       subject.attach(observer2);       subject.attach(observer3);            //要出报纸啦       subject.setContent("本期内容是观察者模式");    }}打印结果张三收到消息了,内容是===本期内容是观察者模式李四收到消息了,内容是===本期内容是观察者模式王五收到消息了,内容是===本期内容是观察者模式

在JDK当中为我们提供好了被观察者对象和观察者对象,当我们需要用到观察者模式时,只需要分别实现被观察者对象和观察者对象即可

被观察者对象Observable

public class Observable {    private boolean changed = false;    private Vector
obs; public Observable() { obs = new Vector<>(); } public synchronized void addObserver(Observer o) { if (o == null) throw new NullPointerException(); if (!obs.contains(o)) { obs.addElement(o); } } public synchronized void deleteObserver(Observer o) { obs.removeElement(o); } public void notifyObservers() { notifyObservers(null); } public void notifyObservers(Object arg) { /* * a temporary array buffer, used as a snapshot of the state of * current Observers. */ Object[] arrLocal; synchronized (this) { if (!changed) return; arrLocal = obs.toArray(); clearChanged(); } for (int i = arrLocal.length-1; i>=0; i--) ((Observer)arrLocal[i]).update(this, arg); } public synchronized void deleteObservers() { obs.removeAllElements(); } protected synchronized void setChanged() { changed = true; } protected synchronized void clearChanged() { changed = false; } public synchronized boolean hasChanged() { return changed; } public synchronized int countObservers() { return obs.size(); }}

java当中提供的被观察者对象考虑到了并发安全性问题使用了Vector,同时增加了一个状态位,用来表示,当前状态是否发生变更,如果发生没有发生变更,就不会通知观察者,如果发生变更了通知所有的观察者,同时将已经变更的状态进行重置,方便下次继续使用。

接下来看观察者对象

public interface Observer {       void update(Observable o, Object arg);}

对于观察者对象来说,只有一个接口,这个方法传递两个参数,一个是被观察者对象,还有一个是自己定义的需要通知的消息,可以看到jdk设计的还是比较合理的,因为可能有时候我们的通知消息是被观察者当中获取,也有可能我们的通知消息是自己定义的。

你可能感兴趣的文章
爆赞!Android岗大厂面试官常问的那些问题,论程序员成长的正确姿势
查看>>
爆赞!Android岗大厂面试官常问的那些问题,论程序员成长的正确姿势
查看>>
爱了爱了!Android平台HTTPS抓包解决方案及问题分析,面试必问
查看>>
爱了爱了!Android开发者值得深入思考的几个问题,送大厂面经一份!
查看>>
牛笔了!Android黑科技保活实现原理揭秘,深度好文
查看>>
牛笔了!这些面试官常问的开发面试题你都掌握好了吗?看这一篇就够了!
查看>>
看完不会的来打我!Android免打包多渠道统计如何实现?面试必会
查看>>
看完全都会了!Android开发热门前沿知识,积累总结
查看>>
看完吊打面试官!海量算法高频面试题精编解析,附带学习经验
查看>>
看完豁然开朗!一线互联网大厂面试真题系统收录!社招面试心得
查看>>
真是经典中的经典!Android开发你需要了解的那些事,深度好文
查看>>
程序员的中年危机,我想谈谈关于Android面试那些事,深度好文
查看>>
程序员真的是吃青春饭吗?面试官6个灵魂拷问,分享一点面试小经验
查看>>
程序员进阶!Android黑科技保活实现原理揭秘,分享一点面试小经验
查看>>
算法太TM重要了!2021年Android春招面试经历,这原因我服了
查看>>
经典好文!想找工作的你还不看这份资料就晚了!快来收藏!
查看>>
经验分享:掌握这套精编Android高级面试题解析,跳槽薪资翻倍
查看>>
美团安卓面试,程序员如何自我学习和成长?先收藏了
查看>>
老师讲的真棒!你的技术真的到天花板了吗?不吃透都对不起自己
查看>>
腾讯T2亲自讲解!你有过迷茫吗?系列篇
查看>>