设计模式学习笔记(3)——观察者模式

版权声明:本文为博主原创,未经博主允许不得转载。 https://blog.csdn.net/weixin_36904568/article/details/89879269

1. 定义

又叫发布-订阅模式、模型-视图模式、源-监听器模式或从属者模式。定义了对象的一对多依赖,让多个观察者对象同时监听某一个主题对象。当主题对象改变状态时,所有依赖者会收到通知并更新

  • 主题:管理状态,在状态发生变化时,通知观察者
    • 推模型:主题对象向观察者推送主题的详细信息,不管观察者是否需要
    • 拉模型:如果观察者需要更具体的信息,由观察者主动到主题对象中获取
  • 观察者
    • 在注册/订阅了主题后,可以收到状态的更新
    • 取消订阅后,不会收到状态的更新

2. 实现

  • 抽象观察者:提供更新接口,在主题发生改变时更新
  • 具体观察者:订阅具体的主题,协调主题的状态
  • 抽象主题:注册、去除、通知观察者
  • 具体主题:保存具体状态

(1)主题

package ObservePattern;

import java.util.List;

/**
 *抽象主题
 */
public interface Subject {
    /**
     * 注册观察者
     * @param observer
     */
    public void registerObserver(Observer observer);
    /**
     * 去除观察者
     * @param observer
     */
    public void removeObserver(Observer observer);
    /**
     * 通知观察者,拉数据
     */
    public void notifyObserver();

    /**
     * 通知观察者,推数据
     * @param status
     */
    public void notifyObserver(Object status);
}

package ObservePattern;

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

/**
 * 具体的主题
 */
public class MainSubject implements Subject{

    //观察者列表
    private List<Observer> observers;

    //具体数据
    private Object status;

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

    @Override
    public void registerObserver(Observer observer) {
        observers.add(observer);
    }

    @Override
    public void removeObserver(Observer observer) {
        observers.remove(observer);
    }

    @Override
    public void notifyObserver() {
        for (Observer observer:
             observers) {
            observer.update();
        }
    }

    @Override
    public void notifyObserver(Object status) {
        for (Observer observer:
                observers) {
            observer.update(status);
        }
    }

    //获取数据
    public Object getStatus() {
        return status;
    }

    //数据发生改变
    public void change(Object status){
        this.status = status;
        System.out.println("拉数据");
        notifyObserver();
        System.out.println("推数据");
        notifyObserver(status);
    }
}

(2)观察者

package ObservePattern;
/**
 * 抽象观察者
 */
public interface Observer {

    /**
     * 取消订阅主题
     */
    public void cancel();
    /**
     * 自己获取数据
     * @param
     */
    public void update();

    /**
     * 直接获取数据
     * @param status
     */
    public void update(Object status);
}

package ObservePattern;

/**
 * 具体观察者A
 */
public class ObserverA implements Observer {

    //具体状态
    private Object status;

    //具体主题
    private Subject subject;

    //订阅主题
    public ObserverA(Subject subject){
        this.subject = subject;
        subject.registerObserver(this);
    }

    //取消订阅
    @Override
    public void cancel() {
        subject.removeObserver(this);
    }

    @Override
    public void update() {
        if (subject instanceof MainSubject){
            this.status = ((MainSubject) subject).getStatus();
            System.out.println("自己拉数据,A知道状态改变了");
        }
    }

    @Override
    public void update(Object status) {
        this.status = status;
        System.out.println("主题推数据,A知道状态改变了");
    }
}

package ObservePattern;

/**
 * 具体观察者B
 */
public class ObserverB implements Observer {

    //具体状态
    private Object status;

    //具体主题
    private Subject subject;

    //订阅主题
    public ObserverB(Subject subject){
        this.subject = subject;
        subject.registerObserver(this);
    }

    //取消订阅
    @Override
    public void cancel() {
        subject.removeObserver(this);
    }

    @Override
    public void update() {
        if (subject instanceof MainSubject){
            this.status = ((MainSubject) subject).getStatus();
            System.out.println("自己拉数据,B知道状态改变了");
        }
    }

    @Override
    public void update(Object status) {
        this.status = status;
        System.out.println("主题推数据,B知道状态改变了");
    }
}

(3)测试

package ObservePattern;

public class Test {
    public static void main(String[] args) {
        Subject subject = new MainSubject();
        Observer observerA = new ObserverA(subject);
        Observer observerB = new ObserverB(subject);
        ((MainSubject) subject).change("test");

    }
}

3. 特点

  • 可以随时添加、删除观察者,无需修改主题
  • 可以独立使用主题或观察者
  • 有多个观察者时,通知顺序不一定相同

4. JAVA内置的支持

  • 主题——Observable类:发送通知
    • setChanged():标记状态改变
    • notifyObservers():通知,拉数据
    • notifyObservers(xxx):发送数据和通知,推数据
  • 观察者——Observer类:接收通知
    • update(Observale x):主题
    • update(Observale x,xxx):主题和数据

猜你喜欢

转载自blog.csdn.net/weixin_36904568/article/details/89879269