常用设计模式之观察者

观察者设计模式

观察者模式(Observer)是软件设计模式的一种,定义了对象之间一种一对多的关系,也就是当一个对象数据发生变化时,会通知与之依赖的其他对象,以相应其数据变化,这种当目标对象数据发生变化时,与之对应的观察者对象数据随之发生变化的,具有一对多通知关系的设计模式叫做观察者设计模式。其实就是发布订阅模式,发布者发布信息,订阅者获取信息,订阅了就能收到信息,没订阅就收不到信息。

关键概念理解
观察者设计模式中主要区分两个概念:

  • 观察者:指观察者对象,也就是消息的订阅者;
  • 被观察者:指要观察的目标对象,也就是消息的发布者。

通知观察者的方式

  • 推:消息以类似广播的形式通知观察者,观察者只能被动、无条件接受;
  • 拉:接收到被观察者的通知,可以自主决定获取消息。

观察者模式的实现
下面通过两种方式实现观察者设计模式的实现,具体如下:

  • 手写观察者设计模式
  • Java API 提供的观察者设计模式 使用 Java API 提供的 Observer 和 Observeable 实现观察者模式

 JAVA API 实现观察者模式:


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

/**
 * Created by gray on 2017/9/20.
 *
 * 观察者设计模式: 如果想要实现观察者模式,则必须依靠java.util包中提供的Observable类和Observer接口
 *
 * 现在很多的购房者都在关注着房子的价格变化,每当房子价格变化的时候,所有的购房者都可以观察得到。
 * 实际上以上的购房者就是观察者,他们所关注的房价就是被观察者
 * 其中要求,被观察者需要继承Observable类,观察则需要实现Observer接口
 */
public class ObserverTest {


    @Test
    public void test() {
        House house = new House(10000);
        HousePriceObserver A = new HousePriceObserver("A");
        HousePriceObserver B = new HousePriceObserver("B");
        HousePriceObserver C = new HousePriceObserver("C");
        house.addObserver(A);
        house.addObserver(B);
        house.addObserver(C);
        System.out.println(house);
        house.setPrice(6000);
        house.setPrice(8000);
    }

    /**
     * 房价的实现(被观察者,继承Observable)
     */
    class House extends Observable {

        private double price;

        public House(double price) {
            this.price = price;
        }

        public double getPrice() {
            return price;
        }

        public void setPrice(double price) {
            if (this.price != price) {
                this.price = price;
                //标注价格已经被更改
                setChanged();
                //通知观察者数据已被更改
                this.notifyObservers(price);
            }
        }

        @Override
        public String toString() {
            return "当前房价为:" + price;
        }
    }

    /**
     * 购房者实现,(观察者,实现Observer接口)
     */
    class HousePriceObserver implements Observer {

        private String name;

        public HousePriceObserver(String name) {
            this.name = name;
        }

        @Override
        public void update(Observable o, Object arg) {
            //这里最好判断一下通知是否来自于房价,有可能来自其它地方
            if (o instanceof House) {
                System.out.println("购物者" + name + "观察到房价已调整为:" + arg);
            }
        }
    }
}

Java内置观察者模式特征

  • 提供了java.util.Observable类和java.util.Observer接口
  • 使用时具体主题(subject/topic)角色需要继承Observable类
  • 具体观察者角色需要实现Observer接口
  • 通知时需要调用setChanged()函数变更状态
  • 通知调用notifyObservers(Object arg)或notifyObservers()函数
  • 如需再次通知,需清除状态变更clearChanged()
  • 具体主题(subject/topic)角色需要继承Observable,有一定的局限性
  • 实现起来比自己实现稍微简单一些

手动实现观察者模式其实和JAVA API 实现观察者模式类似,具体可以参考 观察者 Observer 接口和被观察者也就是观察目标Observable类的实现。其中Observable类的核心是观察者列表obs属性和notifyObservers方法,用于通知实现了Observer接口的观察者,两者之间是通过update方法来传递消息。

你可能感兴趣的:(设计模式)