【设计模式】观察者模式

一、介绍

观察者模式常用于一对多的监听情景,并且被监听者可以实现监听者的回调,也就是说被监听者能够触发监听者的动作,该动作就是回调。
观察者模式的特点:
1.被观察者不知道具体的观察者是谁,只知道自己被观察了,并且在合适的时机进行广播,让感兴趣的观察者知道发生了什么事情。
2.观察者依赖于被观察者,被观察者不依赖于观察者,是单向关系,耦合程度不高。没有被观察者,观察者无法工作;没有观察者,被观察者该干啥干啥,因为被观察者本来就不清楚谁观察他,发广播是被观察的个人行为。
3.通常被观察者出现行为上的变化,需要观察者做出反馈。显然一般情况下观察者并不知道被观察者啥时候会有变化,因此该反馈是一种被动反馈,实现的是一种回调机制。

二、实现

1、自定义接口

被观察者

package com.swust.java.行为型模式.观察者模式x;

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

public class Subject {

    // 所有观察者集合
    protected List<Observer> list = new ArrayList<>();

    public void register(Observer observer){
        list.add(observer);
    }

    public void remove(Observer observer){
        list.remove(observer);
    }

    // 通知所有的观察者更新状态
    public void notifyAllObservers(){
        for (Observer observer : list) {
            observer.update(this);
        }
    }
    
}

/**
 * 主题对象
 * 被观察者
 */
class ConcreteSubject extends Subject{

    private int state;

    public int getState() {
        return state;
    }

    public void setState(int state) {
        this.state = state;
        this.notifyAllObservers();
    }
}

观察者

package com.swust.java.行为型模式.观察者模式x;

public interface Observer {
    void update(Subject subject);
}

public class ObserverA implements Observer{

    private int myState; // myState需要跟目标对象的state值保持一致

    @Override
    public void update(Subject subject) {
        myState = ((ConcreteSubject)subject).getState();
    }

    public int getMyState() {
        return myState;
    }

    public void setMyState(int myState) {
        this.myState = myState;
    }
}

客户端测试类

package com.swust.java.行为型模式.观察者模式x;

public class Client {

    public static void main(String[] args) {

        // 目标对象
        ConcreteSubject subject = new ConcreteSubject();

        // 创建多个观察者
        ObserverA o1 = new ObserverA();
        ObserverA o2 = new ObserverA();
        ObserverA o3 = new ObserverA();

        // 查看观察者状态
        System.out.println(o1.getMyState());
        System.out.println(o2.getMyState());
        System.out.println(o3.getMyState());

        // 将这三个观察者添加到subject对象的观察者队伍中
        subject.register(o1);
        subject.register(o2);
        subject.register(o3);

        // 改变subject的状态
        subject.setState(3000);

        // 查看观察者状态
        System.out.println(o1.getMyState());
        System.out.println(o2.getMyState());
        System.out.println(o3.getMyState());

    }

}

测试结果

0
0
0
3000
3000
3000

2、JDK接口

被观察者

package com.swust.java.行为型模式.观察者模式x.自带接口;

import java.util.Observable;

/**
 * 目标对象
 */
public class ConcreteSubject extends Observable {

    private int state;

    public void set(int s){
        state = s;// 目标状态改变

        setChanged();// 表示目标对象已经做了更改

        notifyObservers(state);// 通知所有观察者
    }

    public int getState() {
        return state;
    }

    public void setState(int state) {
        this.state = state;
    }
}

观察者

package com.swust.java.行为型模式.观察者模式x.自带接口;

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

public class ObserverA implements Observer {

    private int myState;

    @Override
    public void update(Observable o, Object arg) {
        myState = ((ConcreteSubject)o).getState();
    }

    public int getMyState() {
        return myState;
    }

    public void setMyState(int myState) {
        this.myState = myState;
    }
}

测试类

package com.swust.java.行为型模式.观察者模式x.自带接口;

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

        // 创建多个观察者
        ObserverA o1 = new ObserverA();
        ObserverA o2 = new ObserverA();
        ObserverA o3 = new ObserverA();

        // 将这三个观察者添加到subject对象的观察者队伍中
        subject.addObserver(o1);
        subject.addObserver(o2);
        subject.addObserver(o3);

        // 改变subject的状态
        subject.set(666);

        // 查看观察者状态
        System.out.println(o1.getMyState());
        System.out.println(o2.getMyState());
        System.out.println(o3.getMyState());
    }
}

执行结果

666
666
666
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值