设计模式学习笔记——观察者模式

定义

观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。

设计原则

  1. 为了交互对象之间的松耦合设计而努力。

常见实例

  1. 监听器

简单例子

1、自定接口实现。

1、subject主题(被观察者)接口,代码如下:

public interface Subject {
    void addObserver(Observer observer);

    void removeObserver(Observer observer);

    void notifyAllObservers(String content);
}

2、observer观察者接口,代码如下:

public interface Observer {
    void receive(String string);
}

3、subject接口实现,暴走大TV:

public class BaoZouBigTV implements Subject {
    /**
     * 订阅者的列表
     */
    private ArrayList<Observer> observerArrayList;

    BaoZouBigTV() {
        this.observerArrayList = new ArrayList<>();
    }

    @Override
    public void addObserver(Observer observer) {
        observerArrayList.add(observer);
    }

    @Override
    public void removeObserver(Observer observer) {
        int i = observerArrayList.indexOf(observer);
        if (i >= 0) {
            observerArrayList.remove(i);
        }
    }

    @Override
    public void notifyAllObservers(String content) {
        for (Observer observer : observerArrayList) {
            observer.receive(content);
        }
    }

    /**
     * 增加一个暴走大事件,需要通知所有订阅者
     *
     * @param content
     */
    public void addBaoZouThing(String content) {
        notifyAllObservers(content);
    }
}

分析:
(1)拥有一个Observer的列表。
(2)实现接口。
(3)完成自己的方法,增加了暴走事件,通知所有订阅者。
4、观察者实现,用户订阅暴走大TV:

public class Shen implements Observer {
    @Override
    public void receive(String string) {
        System.out.println("Shen收到:" + string);
    }
}

分析:实现了receive即可。

Demo分析:
(1)用户实现了Observer的接口,统一拥有receive的方法实现,在Subject中用Observer接口接收参数,参数一定有receive的方法;
(2)通知所有人时,调用ObserverArrayList中每个Observer的receive方法即可通知到所有人。

2、JAVA API实现

1、上面的subject(可/被观察者)对应于:java.util.Observable,它是一个类,我们需要让自己的类继承它。

import java.util.Observable;

public class BaoZouBigTV extends Observable {
    /**
     * 增加一个暴走大事件,需要通知所有订阅者
     *
     * @param content
     */
    public void addBaoZouThing(String content) {
        setChanged();
        notifyObservers(content);
    }
}

与我们自己设计的不同的是:继承于API实现的Observable类中的方法,有一个setChanged方法,这个方法用于推送,必须调用该方法,我们去调用notifyObservers时才可以成功推送到观察者。
深入源码,我们可以看到这里的逻辑很好理解:
这里写图片描述
Observable有两个通知方法,一个是notifyObservers(),一个是notifyObservers(Object arg),第一个不带参数的方法实际调用了notifyObservers(null)方法。

2、java.util包下还有一个java.util.Observer,对应于我们自己写的接口Observer。

import java.util.Observable;
import java.util.Observer;

public class Shen implements Observer {
    @Override
    public void update(Observable o, Object arg) {
        System.out.println("Shen收到:" + arg);
    }
}

其中覆写的方法update中有两个参数,一个是可观察对象o,它可以让观察者去拉取(get)“可观察者”的某些数据;一个是传进来的参数Object,用于接收可观察对象主动推送的信息。
3、测试。

public class Test {
    public static void main(String args[]) {
        BaoZouBigTV baoZouBigTV = new BaoZouBigTV();
        Shen shen = new Shen();
        Hong hong = new Hong();
        Bin bin = new Bin();
        baoZouBigTV.addObserver(shen);
        baoZouBigTV.addObserver(hong);
        baoZouBigTV.addObserver(bin);
        baoZouBigTV.addBaoZouThing("暴走大事件3");
    }
}

输出:
这里写图片描述
我们会发现:观察者的调用和我们的绑定顺序不同,这点是正常的,我们不能把一些逻辑设计依赖于这个调用顺序。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值