设计模式之观察者模式实践

观察者模式的角色组成

1:抽象主题(Subject)角色:

主题角色把所有的观察者对象的引用保存在一个列表里;每个主题都可以有任何数量的观察者。主题提供一个接口可以加上或撤销观察者对象;主题角色又叫做抽象被观察者(Observable)角色;

抽象主题角色,有时又叫做抽象被观察者角色,可以用一个抽象类或者一个接口实现;在具体的情况下也不排除使用具体类实现。

2:抽象观察者(Observer)角色:

为所有的具体观察者定义一个接口,在得到通知时更新自己;
抽象观察者角色,可以用一个抽象类或者一个接口实现;在具体的情况下也不排除使用具体类实现。

3:具体主题(ConcreteSubject)角色:

保存对具体观察者对象有用的内部状态;在这种内部状态改变时给其观察者发出一个通知;具体主题角色又叫作具体被观察者角色;

具体主题角色,通常用一个具体子类实现。

4:具体观察者(ConcreteObserver)角色:

保存一个指向具体主题对象的引用;和一个与主题的状态相符的状态。具体观察者角色实现抽象观察者角色所要求的更新自己的接口,以便使本身的状态与主题的状态自恰。

具体观察者角色,通常用一个具体子类实现。

这里写图片描述

程序实践

1:Observer

public interface Observer {
    public void update(String str);
}

2:ConcreteObserver1


public class ConcreteObserver1 implements Observer{
    @Override
    public void update(String str) {
        System.out.println("手机客户端--->"+str);
    }

}

3:ConcreteObserver2


public class ConcreteObserver2 implements Observer{
    @Override
    public void update(String str) {
        System.out.println("PC"+ "客户端--->"+str);

    }
}

4:Subject


public interface Subject {
    public void addWatcher(Observer watcher);
    public void removeWatcher(Observer watcher);
    public void notifyWatchers(String str);
}

5:ConcreteSubject


import java.util.ArrayList;
import java.util.List;

public class ConcreteSubject implements Subject{
     // 存放观察者
    private List<Observer> list = new ArrayList<Observer>();

    @Override
    public void addWatcher(Observer watcher) {
         list.add(watcher);
    }

    @Override
    public void removeWatcher(Observer watcher) {
        list.remove(watcher);
    }

    @Override
    public void notifyWatchers(String str) {

        // 自动调用实际上是主题进行调用的
        for (Observer watcher : list)
        {
            watcher.update(str);
        }
    }

}

6:Test

import java.io.IOException;
import java.util.Map;

public class Test {
    public static void main(String[] args) throws NullPointerException, IOException {
        Subject subject = new ConcreteSubject();
        Observer observer1 = new ConcreteObserver1();
        Observer observer2 = new ConcreteObserver2();
        subject.addWatcher(observer1);
        subject.addWatcher(observer2);
        Map<String, Object> map = WeatherUtil.getTodayWeather("101010100");
        subject.notifyWatchers(map.get("city") + ":" + map.get("temp")+ "度(发布时间:"  + map.get("time")+")");


    }
}

运行结果

手机客户端--->北京:10度(发布时间:10:25)
PC客户端--->北京:10度(发布时间:10:25)

观察者模式的应用场景

1、 对一个对象状态的更新,需要其他对象同步更新,而且其他对象的数量动态可变。
2、 对象仅需要将自己的更新通知给其他对象而不需要知道其他对象的细节。

观察者模式的优点:

1、 Subject和Observer之间是松偶合的,分别可以各自独立改变。
2、 Subject在发送广播通知的时候,无须指定具体的Observer,Observer可以自己决定是否要订阅Subject的通知。
3、 遵守大部分GRASP原则和常用设计原则,高内聚、低偶合。

观察者模式的缺陷

1、 松偶合导致代码关系不明显,有时可能难以理解。
2、 如果一个Subject被大量Observer订阅的话,在广播通知的时候可能会有效率问题。(毕竟只是简单的遍历)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

十五楼亮哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值