观察者模式 Java

观察者模式 Java

观察者模式(Observer Pattern)指多个观察者同时依赖于某个主题对象,对象发生改变后会主动通知观察者进行改变的软件设计模式。


主要内容:

  1. 简要原理
  2. 观察者模式实例
  3. 完整工程链接

简要原理

百度百科:
观察者模式

别名:发布(publish)-订阅(subscribe)模式、模型(model)-视图(view)模式、源-收听者模式、从属者模式

观察者模式有两个主要对象:观察者和被观察者,其中,观察者的功能实现依赖于被观察者(比如,观察者是前端界面,被观察者是后台数据,界面需要利用后台数据进行界面展示),当观察者观察到被观察者的状态发生变化后,自身也随之发生变化(比如,界面显示天气信息,当后台天气数据发生变化后,前端会根据变化的数据重新构建界面)。

实现:并不是观察者时刻关注被观察者是否发生变化,而是被观察者包含有观察者对象,而观察者则具体实现了更新方法,当被观察者自身发生变化后,遍历观察者列表,调用更新方法,通知观察者进行相应的变化(即订阅 - 通知 - 撤销订阅的结构)。


观察者模式实例

参考:

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

观察者模式

设计模式之观察者模式

首先定义一个抽象主题,里面实现绑定、撤销、通知观察者的方法,Subject.java 代码如下:

package ObserverModel2;

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

/**
 * Created by Lenovo on 2017/5/15.
 */
public abstract class Subject {

    private List<Observer> list = new ArrayList<>();

    /**
     * 订阅
     *
     * @param observer
     */
    public void Attach(Observer observer) {
        list.add(observer);
    }

    /**
     * 撤销订阅
     *
     * @param observer
     */
    public void Detach(Observer observer) {
        list.remove(observer);
    }

    /**
     * 通知
     */
    public void Notify() {
        System.out.println("Update:");

        for (Observer observer : list) {
            observer.Update();
        }
    }
}

被观察者中包含有一个气候对象(WeatherBean),其中包含有季节(season)、天气(weather),WeatherBean.java 代码如下:

package ObserverModel2;

/**
 * Created by Lenovo on 2017/5/15.
 */
public class WeatherBean {

    /**
     * 季节:春夏秋冬
     */
    private String season;
    /**
     * 天气:冷、热
     */
    private String weather;

    public WeatherBean(String season, String weather) {
        this.season = season;
        this.weather = weather;
    }

    public String getSeason() {
        return season;
    }

    public void setSeason(String season) {
        this.season = season;
    }

    public String getWeather() {
        return weather;
    }

    public void setWeather(String weather) {
        this.weather = weather;
    }

    @Override
    public String toString() {
        return "WeatherBean{" +
                "season='" + season + '\'' +
                ", weather='" + weather + '\'' +
                '}';
    }
}

具体实现被观察者,ConcreteSubject.java 如下:

package ObserverModel2;

/**
 * Created by Lenovo on 2017/5/15.
 */
public class ConcreteSubject extends Subject {

    private WeatherBean weatherBean;

    public ConcreteSubject(WeatherBean weatherBean) {
        this.weatherBean = weatherBean;
    }

    /**
     * 设置季节变换和天气变换
     *
     * @param weatherBean
     */
    public void setWeatherBean(WeatherBean weatherBean) {
        this.weatherBean = weatherBean;

        this.Notify();
    }

    public WeatherBean getWeatherBean() {
        return weatherBean;
    }

    /**
     * 季节变换
     *
     * @param season
     */
    public void setSeason(String season) {
        weatherBean.setSeason(season);

        this.Notify();
    }

    /**
     * 天气变换
     *
     * @param weather
     */
    public void setWeather(String weather) {
        weatherBean.setWeather(weather);

        this.Notify();
    }

    @Override
    public String toString() {
        return "ConcreteSubject{" +
                "weatherBean=" + weatherBean +
                '}';
    }
}

定义一个接口,包含观察者需要实现的更新方法,以便被观察者统一调用,Observable.java 代码如下:

package ObserverModel2;

/**
 * Created by Lenovo on 2017/5/15.
 */
public interface Observable {

    /**
     * 更新接口
     */
    void Update();

}

观察者 Observer.java 代码如下:

package ObserverModel2;

/**
 * Created by Lenovo on 2017/5/15.
 */
public class Observer implements Observable {

    /**
     * 观察者
     */
    private String name;
    /**
     * 具体主题
     */
    private ConcreteSubject subject;

    public Observer(String name, ConcreteSubject subject) {
        this.name = name;
        this.subject = subject;

        // 绑定观察者
        this.subject.Attach(this);

        Update();
    }

    @Override
    public void Update() {
        String str = String.format("name: %s subject: %s", name, subject.toString());
        System.out.println(str);
    }
}

测试代码 Test.java 如下:

package ObserverModel2;

/**
 * Created by Lenovo on 2017/5/16.
 */
public class Test {

    public static void main(String[] args) {
        ConcreteSubject subject = new ConcreteSubject(new WeatherBean("spring", "warm"));

        Observer observer = new Observer("one", subject);
        Observer observer1 = new Observer("two", subject);
        Observer observer2 = new Observer("three", subject);

        // 修改对象
        subject.setSeason("summary");
        subject.setWeather("hot");
    }
}

实现结果:

这里写图片描述

利用Java自带可观察对象 Observable

参考:

Interface Observer:抽象观察者

Class Observable:可观察对象

Java 自带了抽象主题(Observable),以及更新接口(Observer

修改后具体主题(ConcreteSubject.java)代码如下:

package ObserverModel3;

import ObserverModel2.WeatherBean;

import java.util.Observable;

/**
 * Created by Lenovo on 2017/5/16.
 */
public class ConcreteSubject extends Observable {

    private WeatherBean weatherBean;

    public ConcreteSubject(WeatherBean weatherBean) {
        this.weatherBean = weatherBean;
    }

    /**
     * 设置季节变换和天气变换
     *
     * @param weatherBean
     */
    public void setWeatherBean(WeatherBean weatherBean) {
        this.weatherBean = weatherBean;

        Notify();
    }

    public WeatherBean getWeatherBean() {
        return weatherBean;
    }

    /**
     * 季节变换
     *
     * @param season
     */
    public void setSeason(String season) {
        weatherBean.setSeason(season);

        Notify();
    }

    /**
     * 天气变换
     *
     * @param weather
     */
    public void setWeather(String weather) {
        weatherBean.setWeather(weather);

        Notify();
    }

    @Override
    public String toString() {
        return "ConcreteSubject{" +
                "weatherBean=" + weatherBean +
                '}';
    }

    private void Notify() {
        System.out.println("Update:");

        this.setChanged();
        this.notifyObservers(weatherBean);
    }

}

具体观察者(ConcreteObserver.java)代码如下:

package ObserverModel3;

import ObserverModel2.WeatherBean;

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

/**
 * Created by Lenovo on 2017/5/16.
 */
public class ConcreteObserver implements Observer {

    /**
     * 观察者
     */
    private String name;
    /**
     * 具体主题
     */
    private ConcreteSubject subject;

    public ConcreteObserver(String name, ConcreteSubject subject) {
        this.name = name;
        this.subject = subject;

        // 绑定观察者
        this.subject.addObserver(this);

        this.update(null, null);
    }

    @Override
    public void update(Observable o, Object arg) {
        String str = null;
        if (arg != null) {
            WeatherBean bean = (WeatherBean) arg;
            str = String.format("name: %s subject: %s", name, bean.toString());
        } else {
            str = String.format("name: %s subject: %s", name, subject.toString());
        }
        System.out.println(str);
    }
}

测试代码(Test.java)如下:

package ObserverModel3;

import ObserverModel2.WeatherBean;

/**
 * Created by Lenovo on 2017/5/16.
 */
public class Test {

    public static void main(String[] args) {
        ConcreteSubject subject = new ConcreteSubject(new WeatherBean("spring", "warm"));

        ConcreteObserver observer = new ConcreteObserver("one", subject);
        ConcreteObserver observer1 = new ConcreteObserver("two", subject);
        ConcreteObserver observer2 = new ConcreteObserver("three", subject);

        // 修改对象
        subject.setSeason("summary");
        subject.setWeather("hot");
    }
}

完整工程链接

https://git.oschina.net/zjZSTU/observerdemo.git
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值