观察者模式

《Head First Design Pattern》一书中对观察者模式的定义如下: The Observer Pattern defines a one-to-many dependency objects so that when one object changes state, all of its dependents are notified and updated automatically.

观察者设计模式定义了对象间的一种一对多的依赖关系,以便一个对象的状态发生变化时,所有依赖于它的对象都得到通知并自动刷新。 从根本上说,该模式必须包含两个角色:观察者和被观察对象。下面是设计模式中包含角色的UML类图(来自百度百科)。

观察者(Observer)将自己注册到被观察对象(Subject)中,被观察对象将观察者存放在一个容器(Container)里。 被观察对象(Subject)发生了某种变化,从容器中得到所有注册过的观察者,将变化通知观察者。

下面举这样一个例子:比如一个小游戏,A说出一个十进制的数,B说出其对应的二进制结果,C说出其对应的八进制结果,D说出其对应的十六进制结果。 使用观察者模式A可以作为被观察者(Subject),B、C、D可以作为观察者(Observer)。

下面是Java代码示例: 观察者接口:

public interface IObserver {
    public void update();
}

被观察者接口:

public interface ISubject {
    public void addObserver(IObserver o);
    public void deleteObserver(IObserver o);
    public void notifyObservers();
}

实体被观察者A:就是游戏中的A

public class Number implements ISubject {
    private List<IObserver> observers;
    private int number;

    public Number() {
        observers = new ArrayList<IObserver>();
    }

    public void setNumber(int number) {
        this.number = number;
        notifyObservers();
    }

    public int getNumber() {
        return number;
    }

    @Override
    public void addObserver(IObserver o) {
        observers.add(o);

    }

    @Override
    public void deleteObserver(IObserver o) {
        observers.remove(o);

    }

    @Override
    public void notifyObservers() {
        for (IObserver observer : observers) {
            observer.update();
        }
    }
}

实体观察者B:游戏中的B,将A给的数字转成二进制

public class BinTranslator implements IObserver {

    private ISubject subject;

    public BinTranslator(Number number) {
        subject = number;
        subject.addObserver(this);
    }

    @Override
    public void update() {
        if (subject instanceof Number) {
            Number number = (Number) subject;
            int inum = number.getNumber();
            System.out.println(inum + "=" + Integer.toBinaryString(inum));
        }
    }

}

实体观察者D:游戏中的D,将A给的数字转成十六进制

public class HexTranslator implements IObserver {

    private ISubject subject;

    public HexTranslator(Number number) {
        subject = number;
        subject.addObserver(this);
    }

    @Override
    public void update() {
        if (subject instanceof Number) {
            Number number = (Number) subject;
            int inum = number.getNumber();
            System.out.println(inum + "=0x" + Integer.toHexString(inum));
        }
    }
}

观察者模式测试代码:我们开始做游戏了

public class ObserverPattern {
    @SuppressWarnings("unused")
    public static void main(String[] args) {
        Number number = new Number();
        IObserver bin = new BinTranslator(number);
        IObserver hex = new HexTranslator(number);
        number.setNumber(12);
        number.setNumber(-1);
    }
}

运行结果:

12=1100
12=0xc
-1=11111111111111111111111111111111
-1=0xffffffff

其实Java JDK本身提供了设计模式等额实现: java.util.Observer是一个接口,观察者接口,相当于我们上面的IObserver接口。我们需要实现一个观察者的时候只需要实现这个接口就OK了。 java.util.Observable是一个类,被观察者类,我们需要实现一个被观察者的时候只需要继承这个类就OK了。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Leetcode: Count and Say

    题目: The count-and-say sequence is the sequence of integers beginning as follow...

    卡尔曼和玻尔兹曼谁曼
  • 排序(二):希尔排序

    希尔排序的基本思想是:把待排序的数据元素分成若干个小组,对同一小组内的数据元素用直接插入法排序;小组的个数逐次缩小;当完成了所有数据元素都在同一个组内的排序后排...

    卡尔曼和玻尔兹曼谁曼
  • Numpy中如何给矩阵增加一行或一列

    使用Python的numpy的array结构,如何给矩阵增加一行或者一列呢? 下面提供一种方法,当然numpy还提供了很多API函数可供选择。

    卡尔曼和玻尔兹曼谁曼
  • oracle主键自增

    剑行者
  • python笔记2

    循环是编程中非常重要的一个步骤,可以很轻松的完成一些非常繁琐的东西。 使用单数和复数名称可以帮助你判断代码段处理的是单个列表元素1还是整个列表

    blankmiss
  • Django后台管理界面修改(源文件修改)

    治电小白菜
  • python 函数式编程 sorted

    排序也是在程序中经常用到的算法。无论使用冒泡排序还是快速排序,排序的核心是比较两个元素的大小。如果是数字,我们可以直接比较,但如果是字符串或者两个dict呢?直...

    葫芦
  • Java基础04 封装与接口

    总结之前的内容,对象(object)指代某一事物,类(class)指代象的类型。对象可以有状态和动作,即数据成员和方法。

    Java团长
  • Java基础04 封装与接口

    总结之前的内容,对象(object)指代某一事物,类(class)指代象的类型。对象可以有状态和动作,即数据成员和方法。 到现在为止,数据成员和方法都是同时开放...

    Vamei
  • HackTheBox - Poison Writeup

    来源:https://www.absolomb.com/2018-09-08-HackTheBox-Poison/

    安恒网络空间安全讲武堂

扫码关注云+社区

领取腾讯云代金券