图解设计模式

来源:互联网 发布:淘宝新版怎样发布宝贝 编辑:程序博客网 时间:2024/06/06 14:02

读书笔记 仅供参考

简述

观察者模式,当观察对象的状态发生变化时,会通知给观察者。适用于根据对象状态进行相应处理的场景。

角色和 UML

Subject

该角色表示观察对象,定义了注册观察者和删除观察者的方法,同时声明了获取现在状态的方法。

ConcreteSubject

具体的被观察对象,自身状态改变后,会通知已经注册的 Observer 对象。

Observer

负责接收来自 Subject 角色的状态变化的通知。

ConcreteObserver

具体的 Observer,当它的 update 方法被调用后,回去获取要观察的对象的最新状态。

UML

这里写图片描述

例子

例程是一个自动生成数字,通知观察者展示数字的程序。

public interface Observer {    //让被观察者通知观察者状态已经改变    void update(NumberGenerator generator);}
// 以数字形式显示观察到的数值public class DigitObserver implements Observer {    @Override    public void update(NumberGenerator generator) {        System.out.println("DigitObserver: " + generator.getNumber());        try {            Thread.sleep(100);        } catch (InterruptedException e) {        }    }}
// 将观察到的数值以 ***** 的方式显示出来public class GraphObserver implements Observer {    @Override    public void update(NumberGenerator generator) {        System.out.println("GraphObserver: ");        int count = generator.getNumber();        for (int i = 0; i < count; i++){            System.out.print("*");        }        System.out.println();        try {            Thread.sleep(100);        } catch (InterruptedException e) {        }    }}
//作为 Subject 被观察者public abstract class NumberGenerator {    private List<Observer> observers = new ArrayList<>();    public void addObservers(Observer observer) {        observers.add(observer);    }    public void deleteObserver(Observer observer) {        observers.remove(observer);    }    // 向 Observer 发生通知    public void notifyObserers() {        Iterator<Observer> it = observers.iterator();        while (it.hasNext()) {            Observer o = it.next();            o.update(this);        }    }    //获取数值    public abstract int getNumber();    //生成数值    public abstract void execute();}
public class RandomNumberGenerator extends NumberGenerator {    private Random random = new Random();    private int number;    @Override    public int getNumber() {        return number;    }    @Override    public void execute() {        for (int i = 0; i < 20; i++) {            number = random.nextInt(50);            notifyObserers();        }    }}
public class Main {    public static void main(String[] args) {        NumberGenerator generator = new RandomNumberGenerator();        Observer observer1 = new DigitObserver();        Observer observer2 = new GraphObserver();        generator.addObservers(observer1);        generator.addObservers(observer2);        generator.execute();    }}

结果

这里写图片描述

UML

这里写图片描述

要点

  • 实现了可替换性,Subject 不用关注 Observer 的实现
  • Observer 可能会有一定的顺序要求
  • 当 Observer 对 Subject 产生影响时,注意产生循环调用
  • Observer 并不是主动的去观察,而是被动的接收通知
阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 秋刀鱼的滋味 煎刀鱼的做法 长江刀鱼多少钱一斤 秋刀鱼怎么做好吃 秋刀鱼的害处 家炖刀鱼做法 长江刀鱼多少钱 家常炖秋刀鱼 长江刀鱼图片 三刀鱼多少钱一斤 孕妇吃秋刀鱼 刀鱼多少钱一斤2018 炸刀鱼的家常做法 刀鱼的做法大全 秋刀鱼多少钱一斤 刀鱼的做法大全家常 刀鱼怎么做好吃 炖刀鱼的家常做法 带鱼的做法油炸 带鱼 炸带鱼的家常做法 怎么炸带鱼 油炸带鱼怎么做 油炸怎么做 油炸带鱼怎么做好吃 炸带鱼 带鱼怎么做 带鱼怎么炸 油炸带鱼的做法 带鱼的家常做法 怎样炸带鱼又香又脆 油炸带鱼 油炸带鱼的家常做法 怎样炸带鱼 如何炸带鱼 带鱼的做法大全 带鱼做法 油炸带鱼的做法图解 油炸小黄鱼 带鱼怎么做好吃 炸带鱼的做法