设计模式:观察者模式--Observer

一、什么是观察者模式

1、生活中的观察者模式

1、警察抓小偷

在现实生活中,警察抓小偷是一个典型的观察者模式「这以一个惯犯在街道逛街然后被抓为例子」,这里小偷就是被观察者,各个干警就是观察者,干警时时观察着小偷,当小偷正在偷东西「就给干警发送出一条信号,实际上小偷不可能告诉干警我有偷东西」,干警收到信号,出击抓小偷。这就是一个观察者模式

2、装模作样写作业

小时候家里家活比较多,爸妈让我去干活的时候,我偶尔会说我要学习「其实不想去干活,当然只是偶尔,我还是常常干家务的」,然后爸妈就去地里了,我一个人在家里,先摆出一张桌子「上面放好想看的书」,然后打开电视机看起电视剧,但是又怕家里人回到家中看到我在看电视,于是把家里的大门锁住「当爸妈回的时候肯定要开门」,当我听见开门声就会立马关掉电视,做到作业桌上「装模作样写作业」----在这过程中:我充当的就是观察者,爸妈就是被观察者,他们开门就会触发门响「相当于告诉我说他们回来了」,我听到响声「关电视,写作业」,有过类似的经验的朋友们下面点个赞

3、远程视频会议等

老板和员工远程开会:老板是被观察者,员工是观察者。微信公号:微信公号作者是被观察者,微信用户是观察者「当公号作者发送一篇文章,关注了公号的观察者都可以收到文章」等

2、程序中的观察者模式

观察者模式的定义

观察者模式描述的是一种一对多的关系「一个被观察者对应多个观察者」,当被观察者的状态发生改变时,所有观察者都会得到通知。通俗的理解:观察者模式就是在特定的时刻「被观察者发送通知」干特定的事情「观察者收到通知处理自己相应的事件」

观察者模式的特点

观察者模式的三要素:观察者,被观察者,事件「订阅」

观察者模式的结构

角色 类别 说明
Subject 接口或抽象类 主题也叫被观察者
RealSubject 真实的主题类 具体的被观察者,内部维护了观察者的列表
IObserver 观察者接口或抽象类 抽象出观察者的接口
RealObserver 具体的观察者 被观察者有更新,观察者立马响应更新

观察者模式简单的 UML

二、观察者模式举例

在举例之前,我们先看看一个概念--回调,什么是回调:就调用一圈又回到自已了「通俗的就可以这样认为」

1、回调

例子一:小明叫爸爸吃饭

举个例子,小明妈妈做好了饭,让小明去地里叫他爸回来吃饭,小明说好的我马上去,过了半个小时小明和他爸一起来了,小明给妈妈的说:“妈,爸回来了”,妈妈说:“好的我知道了,让你爸洗洗手吃饭吧”,在这一过程中,小明给妈妈的说:“妈,爸回来了”就是一个回调,不好理解?那看代码吧

小明叫爸爸吃饭简单的 UML

写代码

  • 1、定义一个回调接口

  • 2、定义妈妈类

  • 3、定义小明类

  • 4、测试

  • 5、运行查看结果

这就是回调,我们看看的数据的走向 Mom-->xiaoming-->Mom 转了一圈回来了,这就是回调

例子二,模拟Android 中 View 的点击事件

经过例子一,我敢保证多数朋友对回调还是稀里糊涂,不要紧,我们再来一个例子感受一下,做过 Android 的朋友一定调用过 View.setOnclickListener(OnClickListener onClickListener) 点击函数,没错 OnClickListener 就是一个回调接口,我们来使用 java 代码模拟一下这个过程

先看一下 UML

根据 UML 写代码

  • 1、 定义一个 View 类
public class View {

    private OnClickListener onClickListener ;
    // 触发点击事件
    protected void click(){
        if(onClickListener !=null){
            onClickListener.onClick(this);
        }
    }
    // 设置回调
    public void setOnClickListener(OnClickListener onClickListener){
        this.onClickListener = onClickListener ;
    }

    public interface OnClickListener{
        // 定义回调方法
        void onClick(View v) ;
    }
}
  • 2、定义一个 Button 类
/**
 * Created by TigerChain
 * 定义一个按钮
 */
public class Button extends View {
    public void click(){
        super.click();
    }
}
  • 3、测试类 Test
public class Test {

    public static void main(String args[]){
        Button button = new Button() ;
        //看到了没,看到这里是不是很亲切,是不是发现 次哦! 这就是回调
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                System.out.print("自定义 View 的回调事件");
            }
        });
        // 模拟用户点击这个运作,Android 系统的 View 是重写手势来调用这个方法的,没有暴露给用户
        button.click();
    }
}
  • 4、运行查看结果

如果你看 Android 源码,或是三方的源码会发现好多这样的回调方法,比如网络请求成功失败的回调等。

使用观察者模式实现自定义 View

  • 定义 View 「被观察者」
public class View {
    //被观察者的列表
    private ArrayList<OnClickListener> onClickListeners = new ArrayList<>() ;
    // 触发通知
    protected void click(){
        for(OnClickListener onClickListener:onClickListeners){
            if(onClickListener !=null){
                onClickListener.onClick(View.this);
            }
        }
    }
    // 注册观察者
    public void setOnClickListener(OnClickListener onClickListener){
        onClickListeners.add(onClickListener) ;
    }

    public interface OnClickListener{
        // 定义通知的方法
        void onClick(View v) ;
    }

    public void unRegister(OnClickListener onClickListener){
        if(onClickListeners.contains(onClickListener)){
            onClickListeners.remove(onClickListener) ;
        }
    }
}

注意这里的 OnClickListener 就是抽象的观察者

  • 2、定义一个 Button
/**
 * Created by TigerChain
 */
public class Button extends View {

}
  • 3、测试 Test
public class Test {
    public static void main(String args[]){
        //定义一个被观察者
        Button button = new Button() ;
        //注册其中一个观察者
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                System.out.println("TigerChain");
            }
        });
        // 注册另一个观察者
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                System.out.println("never give up");
            }
        });
        // 被观察者触发事件
        button.click();
    }
}
  • 4、运行查看结果

PS:总结看到了没,观察者模式和回调是如此的相似,如果我们把上面的注册观察者改成一个「和 View 回调一模一样」,可以说回调是一种特殊的观察者模式,回调和观察者联系和区别

  • 1、回调可以说只有一个观察者,是一对一,是一种特殊的观察者模式「我是这样的认为的,个人观点,如果有误欢迎指出」
  • 2、观察者被观察者持有观察的列表,是一种一对多的关系
  • 3、回调是一种监听方式,观察者模式是一种解决方案「设计模式」

有了回调的基础,下面我们来看看观察者模式的几个精典例子

2、观察者举例

1、微信公号推送文章

最近看了我文章的人都知道我最近在写关于设计模式这一系列,在这里我「TigerChain」就是一个被观察者,普通的微信用户就是观察者,如果微信用户关注了 TigerChain ,那么我推送的每一篇的文章,微信用户就会第一时间收到我的文章「订阅 TigerChain的用户」,这就是一个典型的观察者模式

微信公号推送文章简单的 UML

根据 UML 撸码

  • 1、定义抽象的被观察者 IWxServerSubject.java
/**
 * Created by TigerChain
 * 定义主题「被观察者接口」,所有的公号作者共同属性「其实这里功能上微信系统的功能,直接抽象成被观察者」
 */
public interface IWxServerSubject {
    // 添加观察者
    void attchObserver(IObserver iObserver) ;
    // 移除观察者
    void detachObserver(IObserver iObserver) ;
    // 通知观察者
    void notifyObserver() ;
}
  • 2、定义抽象的观察者接口 Observer.Java
/**
 * Created by TigerChain
 * 定义观察者接口,即关注公号的微信用户共同属性
 */
public interface Observer {
    // 观察者收到信息,内容为 info
    void reciveContent(String info) ;
}
  • 3、定义具体的被观察者「公号作者 TigerChain」 TigerChainSubject.java
/**
 * Created by TigerChain
 * 定义一个真实的被观察者 TigerChain「公号的作者」
 * 里面存了订阅 TigerChain 微信公众账号的读者
 */
public class TigerChainSubject implements IWxServerSubject {

    // 订阅者列表「观察者列表」,即关注 TigerChain 公号的读者
    private List<IObserver> observers = new ArrayList<>() ;
    //作者更新公号的内容
    private String updateContent ;

    @Override
    public void attchObserver(IObserver iObserver) {
        observers.add(iObserver) ;
    }

    @Override
    public void detachObserver(IObserver iObserver) {
        if(observers.contains(iObserver)) {
            observers.remove(iObserver);
        }
    }

    @Override
    public void notifyObserver() {
        for (IObserver iObserver:observers) {
            iObserver.reciveContent(updateContent);
        }
    }

    /**
     * 是否关注我的公号
     * @param iObserver
     * @return
     */
    public boolean isAttchObserver(IObserver iObserver){
        return observers.contains(iObserver) ;
    }

    /**
     * TigerChain 在公号中发布文章
     * @param updateContent
     */
    public void submitContent(String updateContent){
        this.updateContent = updateContent ;
        this.notifyObserver();
    }
}
  • 4、定义一个具体的观察者「普通的微信用户」 ReaderObserver.java
/**
 * Created by TigerChain
 * 微信用户
 */
public class ReaderObserver implements Observer {

    // 微信用户的姓名
    private String name ;

    public ReaderObserver(String name){
        this.uname = name ;
    }

    @Override
    public void reciveContent(String info) {
        System.out.println(uname+"注意,TigerChain 发送了文章---"+info);
    }

    public String getUname(){
        return this.name ;
    }
}

可以看到微信用户有接收推送文章的能力「前提是要关注公号作者」

  • 5、来个 Test 类测试一下吧
/**
 * Created by TigerChain
 * 测试类
 */
public class Test {
    public static void main(String args[]){

        IWxServerSubject iWxServerSubject = new TigerChainSubject() ;
        // 微信用户
        ReaderObserver zhangsai = new ReaderObserver("张三") ;
        ReaderObserver lisi = new ReaderObserver("李四") ;
        ReaderObserver wangwu = new ReaderObserver("王五") ;
        ReaderObserver zhaoLiu = new ReaderObserver("赵六") ;

        // 微信用户张三关注我的公号「即订阅」
        iWxServerSubject.attchObserver(zhangsai);
        // 微信用户李四关注我的公号「即订阅」
        iWxServerSubject.attchObserver(lisi);
        // 微信用户王五关注我的公号「即订阅」
        iWxServerSubject.attchObserver(wangle);

        // 我「被观察者」发布了一篇文章--观察者模式
        ((TigerChainSubject)iWxServerSubject).submitContent("人人都会设计模式:观察者模式") ;

        boolean isAttch = ((TigerChainSubject)iWxServerSubject).isAttchObserver(zhaoLiu) ;
        if(!isAttch){
            System.out.println(zhaoLiu.getUname()+"你好!你还没有关注 TigerChain ,请关注先,谢谢");
        }
    }
}

我们看到和现实情况一样,普通微信用户关注公号作者,然后作者发送文章,用户就可以收到文章了

  • 6、运行查看结果

2、狼王开会

话说冬天来了,狼得找过冬的食物,狼王组织如开了紧急会议,下面的群狼都看着狼王传递会议精神和安排任务,此时狼王就是被观察者,群狼就是观察者,我们来看看 UML

狼王开会简单的 UML

根据 UML 撸码

  • 1、抽象被观察者功能 Wolf.Java
/**
 * Created by TigerChain
 * 抽象的被观察者
 */
public interface Wolf {
    // 添加观察者
    void attchObserver(NormalWolf observer) ;
    // 移除观察者
    void detchObserver(NormalWolf observer) ;
    // 通知观察者
    void notifyObserver(String str) ;
}
  • 2、抽象观察者普通的狼 NormalWolf.java
/**
 * Created by 抽象的观察者,普通的狼
 */
public abstract class NormalWolf {

    // 拿到被观察者的引用
    protected IWolf iWolf ;

    /**
     * 收到狼王下达的命令
     * @param str
     */
    public abstract void reciveCommand(String str) ;
}
  • 3、定义具体的被观察者狼王 LangWang.java

由于一个狼群中只有一个狼王,所以狼王是一个单例「学以致用,这里把单例模式也使用一把」

/**
 * Created by TigerChain
 * 狼王「被观察者,下面的狼都看狼王的眼色行事」,是一个单例模式
 */
public class LangWang implements Wolf{

    private static LangWang instance ;
    private LangWang(){}
    public static LangWang getInstance(){
        if(instance == null){
            synchronized (LangWang.class){
                if(instance == null){
                    instance = new LangWang() ;
                }
            }
        }
        return instance ;
    }

    // 除过狼王外的狼「观察者」
    private List<NormalWolf> observers = new ArrayList<>() ;
    // 狼王下达的命令
    private String mingLing  ;

    @Override
    public void attchObserver(NormalWolf observer) {
        observers.add(observer);
    }

    @Override
    public void detchObserver(NormalWolf observer) {
        if(observers.contains(observer)){
            observers.remove(observer) ;
        }
    }

    @Override
    public void notifyObserver(String str) {
        for(NormalWolf observer:observers){
            observer.reciveCommand(str);
        }
    }

    /**
     * 下达命令
     * @param mingLing
     */
    public void xiaDaMingling(String mingLing){
        this.mingLing = mingLing ;
        this.notifyObserver(mingLing);
    }
}
  • 4、定义一个观察者侦查狼 ZhenChaLang.java
/**
 * Created by TigerChain
 * 侦查狼,另一个观察者
 */
public class ZhenChaLang extends NormalWolf {

    public ZhenChaLang(IWolf iWolf){
        this.iWolf = iWolf ;
        this.iWolf.attchObserver(this);
    }

    @Override
    public void reciveCommand(String string) {
        System.out.println("侦查狼:狼王开会传递的信息是 \n"+string);
    }
}

在这里我们实例化一个侦查狼的时候就会把它注册到被观察者中,也就是狼王开会的时候,群狼肯定狼群中的一员「外来狼可不行」,只有内部狼「内部会员」才有资格开会「这种关系就相当于注册这个过程」

  • 5、定义另一个观察者捕猎狼 BuLieLang.java
/**
 * Created by TigerChain
 * 捕猎狼---观察者
 */
public class BuLieLang extends NormalWolf {

    public BuLieLang(IWolf iWolf){
        this.iWolf = iWolf ;
        // 添加观察者,即捕猎狼放在狼王组织中
        this.iWolf.attchObserver(this);
    }

    @Override
    public void reciveCommand(String string) {
        System.out.println("捕猎狼:狼王开会传递的信息是 \n"+string+"\n");
    }
}
  • 测试类 Test
/**
 * Created by TigerChain
 * 测试类
 */
public class Test {
    public static void main(String args[]){
        // 使用单例模式
        LangWang langWang = LangWang.getInstance() ;

        BuLieLang buLieLang = new BuLieLang(langWang) ;
        ZhenChaLang zhenChaLang = new ZhenChaLang(langWang) ;

        // 狼王下达命令就是发送通知
        langWang.xiaDaMingling("1、分工合作,捕猎狼根据侦查狼反馈看机行事 \n" +
                                     "2、侦查狼永远把危险放在第一位,遇到危险第一时间提醒大家撤退");

    }
}
  • 6、运行查看结果

狼王下达命令就是发送通知,那么现场中的狼都会收到通知,典型的观察者模式

3、自定义 EventBus

在 Android 中我们常常使用 EventBus,它相当于是一个单例广播,我们来自定义一个简单的 EventBus 「不考虑线程切换」,其实它也是一种观察者模式「俗称发布、订阅模式」

自定义 EventBus 简单的 UML

代码这里不贴了,我已经上传到 github 上了,大家可以自行看看:https://github.com/githubchen001/DesignPattern/tree/master/app/src/main/java/designpattern/jun/com/designpattern/Observer/CustomEventBus

三、Android 源码中的观察者模式

1、RecyclerView 中使用观察者模式

RecyclerView 中观察者模式简单的 UML

源码就不分析了「贴出代码估计又得一篇来说」,给出下面流程,大家自行看一下就明白了,动动手印象更深

从 setAdapter 开始看一下观察者流程

2、ViewTreeObserver

ViewTreeObserver 是用来监听视图树的观察者,如果视图树发生全局改变的时候就会收到通知

其中,被观察者是 ViewTree ,观察者是 ViewTreeObserver

抽取 ViewTreeObserver 部分代码讲解

这里说说 view.getViewTreeObserver().addOnGlobalLayoutListener(xxx) 场景,其它的雷同

public final class ViewTreeObserver {
    ...
 public interface OnGlobalLayoutListener {
        public void onGlobalLayout();
 }

    ...
// 添加监听器
public void addOnGlobalLayoutListener(OnGlobalLayoutListener listener) {
        checkIsAlive();

        if (mOnGlobalLayoutListeners == null) {
            mOnGlobalLayoutListeners = new CopyOnWriteArray<OnGlobalLayoutListener>();
        }

        mOnGlobalLayoutListeners.add(listener);
    }
}

 ...
    // 分发事件相当于发送通知,即被观察者调用--View
  public final void dispatchOnGlobalLayout() {
        final CopyOnWriteArray<OnGlobalLayoutListener> listeners = mOnGlobalLayoutListeners;
        if (listeners != null && listeners.size() > 0) {
            CopyOnWriteArray.Access<OnGlobalLayoutListener> access = listeners.start();
            try {
                int count = access.size();
                for (int i = 0; i < count; i++) {
                    access.get(i).onGlobalLayout();
                }
            } finally {
                listeners.end();
            }
        }
    }

现在我们有了观察者 ViewTreeObserver ,观察者是 ViewTree 我们说了,主要问题的就是 dispatchOnGlobalLayout 谁调用了,只有触发了这个方法那么事件就回调回来了「这个方法肯定是被观察者调用了,系统调用的」,方法在 ViewRootImpl「关于 ViewRootImpl 可自行去查看,不在本篇的范围」 中体现出来了

看看 ViewRootImpl 的部分代码

public final class ViewRootImpl implements ViewParent,
        View.AttachInfo.Callbacks, ThreadedRenderer.DrawCallbacks {
 ...
 private void performTraversals(){
    ...
    // 执行测量
    performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
    ...
    // 执行布局
    performLayout(lp, mWidth, mHeight);
    ...

    if (triggerGlobalLayoutListener) {
        mAttachInfo.mRecomputeGlobalAttributes = false;
        // 注意看这里,这里触发了 dispatchOnGlobalLayout 方法,系统调用
        mAttachInfo.mTreeObserver.dispatchOnGlobalLayout();
    }
    ...
    // 执行绘制
    performDraw();
    ...
 }
 ...
}

看到了没,mAttachInfo.mTreeObserver.dispatchOnGlobalLayout() 方法是在 ViewRootImpl 中调用了「即是 View 调用了,只要 View 树而已发生改变,就会调用」,是由系统调用的「View 的布局完成这后,就会调用」,并且还调用了自定义 View 的测量,布局,绘制方法。

使用场景:比如我们想在 Activity 的 onCreate() 方法中取得某个 View 的宽高,此时是取不到的,由于布局还没有完成加载之前取到的是 0 ,所以使用 view.getViewTreeObserver().addOnGlobalLayoutListener(xxx) 里面就可以获取到 view 的宽高了,demo 代码如下

  view.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {// 当layout执行结束后回调
                //使用完必须撤销监听(只测量一次),否则,会一直不停的不定时的测量,这比较耗性能
                view.getViewTreeObserver().removeOnGlobalLayoutListener(this);//Added in API level 16
                //view.getViewTreeObserver().removeGlobalOnLayoutListener(this);//废弃了
                int width = view.getMeasuredWidth();
                int width2 = view.getWidth();//和上面的值是一样的
            }
        });

3、ListView

ListView 中使用观察者模式和 RecyclerView 类似,大家可以扒扒这部分源码,这里就不说了

四、观察者模式的优缺点

优点

  • 1、解耦,被观察者只知道观察者列表「抽象接口」,被观察者不知道具体的观察者
  • 2、被观察者发送通知,所有注册的观察者都会收到信息「可以实现广播机制」

缺点

  • 1、如果观察者非常多的话,那么所有的观察者收到被观察者发送的通知会耗时
  • 2、观察者知道被观察者发送通知了,但是观察者不知道所观察的对象具体是如何发生变化的
  • 3、如果被观察者有循环依赖的话,那么被观察者发送通知会使观察者循环调用,会导致系统崩溃

到此为止,我们的观察者模式就说完了,一定要扒扒 Android 源码中相应的观察者模式,你会有一种恍然大悟的感觉

参考:人人都会设计模式:观察者模式--Observer

原文地址:https://www.cnblogs.com/aspirant/p/9442012.html

时间: 2024-10-12 18:07:21

设计模式:观察者模式--Observer的相关文章

设计模式 - 观察者模式(Observer Pattern) 详解

观察者模式(Observer Pattern) 详解 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26583157 版权所有, 禁止转载, 如有转载, 请站内联系. 观察者模式(Observer Pattern): 定义了对象之间的一对多的依赖, 这样一来, 当一个对象改变状态时, 它的所有依赖者都会收到通知并自动更新. 使用方法: 1. 首先新建主题(subject)接口, 负责注册(register)\删除(remove

设计模式 - 观察者模式(Observer Pattern) Java内置 使用方法

观察者模式(Observer Pattern) Java内置 使用方法 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26601659 观察者模式(observer pattern)详解, 参见: http://blog.csdn.net/caroline_wendy/article/details/26583157 Java内置的观察者模式, 是通过继承父类, 实现观察者模式的几个主要函数: Observerable(可被观

说说设计模式~观察者模式(Observer)

观察者模式,也叫发布/订阅模式(publish/subscribe),监视器模式等.在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知.这通常透过呼叫各观察者所提供的方法来实现.. 何时能用到它? 此种模式通常被用来实现事件处理系统,例如,当一个数据仓储操作中,它的添加功能可能会有一个功能,当添加被触发时,所以订阅了这个添加事件需求的代码 块,都会被触发执行,在这个过程中,数据仓储的添加操作就是被观察者,而所以的订阅者就是它的观察者,发被观察者在某种情况

设计模式 - 观察者模式(Observer Pattern) 详细说明

观察者模式(Observer Pattern) 详细说明 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26583157 版权全部, 禁止转载, 如有转载, 请站内联系. 观察者模式(Observer Pattern): 定义了对象之间的一对多的依赖, 这样一来, 当一个对象改变状态时, 它的全部依赖者都会收到通知并自己主动更新. 用法: 1. 首先新建主题(subject)接口, 负责注冊(register)\删除(remo

设计模式--观察者模式Observer(对象行为型)

一.观察者模式 观察者模式是在对象之间定义一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象都会收到通知,并自动更新.观察者模式也被称之为:主题-观察者模式,发布-订阅模式,前者是一,后者是多. 二.UML类图 三.示例 //观察者 class Observer { public: Observer() {} virtual ~Observer() {} virtual void Update() {} }; //博客 class Blog { public: Blog() {} virt

C#设计模式——观察者模式(Observer Pattern)

一.概述在软件设计工作中会存在对象之间的依赖关系,当某一对象发生变化时,所有依赖它的对象都需要得到通知.如果设计的不好,很容易造成对象之间的耦合度太高,难以应对变化.使用观察者模式可以降低对象之间的依赖,以松耦合的方式实现这一目标.二.观察者模式观察者模式定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新.其结构图如下: Subject知道它的所有观察者并提供了观察者注册和删除订阅的接口.Observer为那些在目标发生改变时需获得通知的对象定义

23种设计模式--观察者模式-Observer Pattern

一.观察者模式的介绍      观察者模式从字面的意思上理解,肯定有两个对象一个是观察者,另外一个是被观察者,观察者模式就是当被观察者发生改变得时候发送通知给观察者,当然这个观察者可以是多个对象,在项目我们经常会用这些例子,这样避免了我们使用接口等那些依赖,比如电商项目中得降价通知,然后在来个生活中具体一点的比如公交车的例子,每一站都会对乘客进行提醒等等,我列举的这2个例子在我GITHUb上都有体现:下面用降价通知的Demo给大家具体来说一下,具体的代码还需要大家去下载观看: 二.观察者模式De

Java设计模式之观察者模式(Observer Pattern)

Observer Pattern 是一种常用的设计模式,它是一种事件监听模型.该模式有两个角色,一个是Subject, 另一个是Observer.Subject 保存有多个Observer的引用,一旦特定的事件发生,Subject会通知它所有的Observer,Observer得到该通知后执行相关程序逻辑.其中,Observer只有先向Subject注册后才能被Subject知晓.这就像订报纸,只有我们向出版社提出订报的申请,出版社才会把我们列入订阅者名单,然后每当新报纸印好时,出版社会通知订阅

[Android&amp;amp;Java]浅谈设计模式-代码篇:观察者模式Observer

观察者,就如同一个人,对非常多东西都感兴趣,就好像音乐.电子产品.Game.股票等,这些东西的变化都能引起爱好者们的注意并时刻关注他们.在代码中.我们也有这种一种方式来设计一些好玩的思想来.今天就写个Demo来描写叙述一下这种思想,用java内置的Observer来实现这一思想. 好,程序猿是不善言语的,看代码先. 1.demo的结构: 2.先创建我们的主题类Subject,他就是我们本demo的明星类.继承了Observable,顾名思义,就是被观察的类 .其它观察者对他但是虎视眈眈哦(事实上

设计模式之观察者模式(Observer)摘录

23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于如何创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而一个对象创建型模式将实例化委托给另一个对象.创建型模式有两个不断出现的主旋律.第一,它们都将关于该系统使用哪些具体的类的信息封装起来.第二,它们隐藏了这些类的实例是如何被创建和放在一起的.整个系统关于这些对象所知道的是由抽象类所定义的接口.因此,创建型模式在什么被创建,谁创建它,它是怎样被创建的,以