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

一、介绍

观察者模式,也称为发布-订阅模式。通俗来说,就是定义一个关于观察者和被观察对象的依赖关系,使得当对象状态发生改变时,观察者会得知这一变化。区别于传统的轮询方式。

观察者可以称为订阅者,被观察对象可以称为发布者。当有新内容发布时,订阅者会收到通知。

二、思想

这是怎么做到的呢,其实核心思想是被观察对象维持一个观察者对象列表,当对象状态发生改变时,就通过调用列表中的观察者的通知方法,这样以来,就可以达到在改变的时候顺便通知观察者了的效果。

三、实现

观察者模式里有四个角色:

1、抽象主题(Subject):持有观察者对象引用的集合。有增加和删除观察者的方法。
2、具体主题(ConcreteSubject):有关的状态放在具体主题里,在改变状态时通知集合中的观察者。
3、抽象观察者(Observer):为具体观察者提供一个提醒接口。
4、具体观察者(ConcreteObserver):实现具体接口。

还是看代码比较实在。

Subject:

/**
 * 目标对象,持有观察者集合,提供注册和移除观察者的接口
 * @author ch
 *
 */
public class Subject {
    //观察者集合
    private List<Observer> observers = new ArrayList<Observer>();

    /**
     * 添加指定观察者到集合中  
     * @param observer
     */
    public void attach(Observer observer){
        observers.add(observer);
    }

    /**
     * 删除指定观察者
     * @param observer
     */
    public void detach(Observer observer){
        observers.remove(observer);
    }

    /**
     * 只允许子类调用,用protected修饰符
     * 向所有注册的观察者发送消息
     */
    protected void notifyObservers(){
        for(Observer observer : observers){
            //传入subject,让观察者获取到对象的状态
            observer.update(this);
        }
    }



}

ConcreteSubject:

/**
 * 具体的目标对象,把有关状态存储到相应的观察者对象中
 * @author ch
 *
 */
public class ConcreteSubject extends Subject {

    //目标的对象状态
    private String subjectState;

    public String getSubjectState() {
        return subjectState;
    }

    /**
     * 保存目标状态时,通知观察者
     * @param subjectState
     */
    public void setSubjectState(String subjectState) {
        this.subjectState = subjectState;
        this.notifyObservers();
    }

}

Observer

/**
 * 观察者接口,定义一个更新的接口,是让目标发生变化时需要被通知的对象使用的
 * @author ch
 * 
 */
public interface Observer {
    //观察者更新状态接口,参数是传入的对象,方便获取目标对象的状态
    void update(Subject subject);
}

ConcreteObserver

/**
 * 具体的观察者对象,实现更新的方法,是自身状态和目标状态保持一致
 * @author ch
 *
 */
public class ConcreteObserver implements Observer {

    //观察者的名称,自定义
    private String name;
    //观察者对象状态,从目标出获取
    private String observerState;
    /**
     * 获取目标对象的状态,同步到观察者的状态
     */
    @Override
    public void update(Subject subject) {

        observerState = ((ConcreteSubject)subject).getSubjectState();
        System.out.println(name + "收到消息,对象状态发生改变为: " + observerState);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

Client

public class Client {

    public static void main(String[] args) {
        //创建目标对象
        Subject subject = new ConcreteSubject();

        //创建观察者
        ConcreteObserver ob1 = new ConcreteObserver();
        ob1.setName("observerOne");

        ConcreteObserver ob2 = new ConcreteObserver();
        ob2.setName("observerTwo");

        //注册观察者
        subject.attach(ob1);
        subject.attach(ob2);

        //改变目标状态
        ((ConcreteSubject)subject).setSubjectState("已改变");

    }

}

运行结果:
这里写图片描述

总结:

观察者模式的核心就是subject持有观察者对象的List集合,在对象改变状态时,同时通知注册在集合中的观察者们,调用观察者的update方法。从而达到即时通知,也就是发布订阅的效果。

发布了52 篇原创文章 · 获赞 16 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/Tuzi294/article/details/72775822