设计模式之-----观察者模式

设计模式之-----观察者模式

定义:

  • 定义了对象之间 一对多的依赖关系,其中被观察者是一方,观察者是多方,在被观察者发生改变时,被观察者主动调用方法,通知所有观察者的一种设计模式。

原理:

  • 定义
    ①被观察者类,内部需要实现本身业务数据的存储,有保存所有观察者的一个数据结构类,
    ②观察者统一接口,定义一个统一通知方法,供被观察者数据改变后进行调用通知。
    ③声明观察者和被观察者对象,被观察者和观察者一对多绑定之后,被观察者数据发生改变之后,主动调用观察者的抽象接口方法进行通知。

此设计模式优缺点:

优点的话:

  • 观察者与被观察者业务逻辑相互解耦
  • 有一套触发机制

缺点:

  • 如果被观察者的观察者对象很多的话,全部通知到会很耗时
  • 观察者与被观察者直接如果存在循环依赖的话,会出现问题
  • 没有具体变化详情的通知机制,观察者只是知道被观察者发生变化了

注意事项:

  • 避免循环引用
  • 防止观察者发生崩溃,会导致在被观察者向外通知时发生异常

其中JDK中提供了一套机制,下面依托于JDK实现一个观察者模式的demo:

  • 被观察者:
    java.util.Observable
  • 观察者对象抽象接口:
    java.util.Observer
  • 源码分析:
    其中 Observable类中的代码结构如下:
//线程同步
public class Observable {
	//是否变更标识符
    private boolean changed = false;
    //观察者列表,继承自 AbstractList,实现了 List<E>, 
    //RandomAccess, Cloneable, Serializable 这些接口的列表结构
    private Vector<Observer> obs = new Vector();

    public Observable() {
    }
	//绑定观察者
    public synchronized void addObserver(Observer var1) {
        if (var1 == null) {
            throw new NullPointerException();
        } else {
        	//防止重复添加
            if (!this.obs.contains(var1)) {
                this.obs.addElement(var1);
            }
        }
    }
	//注销观察者
    public synchronized void deleteObserver(Observer var1) {
        this.obs.removeElement(var1);
    }
    //无参方式通知观察者,
    public void notifyObservers() {
        this.notifyObservers((Object)null);
    }
	//有参数式通知,实现方式:循环  可能导致的问题,一个观察者发生崩溃,程序崩溃
    public void notifyObservers(Object var1) {
        Object[] var2;
        synchronized(this) {
            if (!this.changed) {
                return;
            }

            var2 = this.obs.toArray();
            this.clearChanged();
        }

        for(int var3 = var2.length - 1; var3 >= 0; --var3) {
            ((Observer)var2[var3]).update(this, var1);
        }

    }

    public synchronized void deleteObservers() {
        this.obs.removeAllElements();
    }

    protected synchronized void setChanged() {
        this.changed = true;
    }

    protected synchronized void clearChanged() {
        this.changed = false;
    }

    public synchronized boolean hasChanged() {
        return this.changed;
    }

    public synchronized int countObservers() {
        return this.obs.size();
    }
}

  • 观察者抽象接口源码:
//将观察者抽象出来,
public interface Observer {
	//被观察者这主动通知时,调用此方法:
    void update(Observable var1, Object var2);
}

实现就很简单了,如下:

  • 实现被观察者类
/**
 * @author GerryRun
 * @date 2020/9/21 14:52.
 * @email gerryin@163.com
 * @desc 被观察者
 */
public class Subject extends Observable {

    private int statue;

    public int getStatue() {
        return statue;
    }

    public void setStatue(int statue) {
        this.statue = statue;
        //被观察者 发生改变,主动通知观察者
        this.setChanged();
        this.notifyObservers();
    }
}
  • 实现观察者类(实现Observer接口):
/**
 * @author GerryRun
 * @date 2020/9/21 14:55.
 * @email gerryin@163.com
 * @desc 观察者 一号
 */
public class OneObserver implements Observer {

    public OneObserver(Observable observable) {
        //与被观察者绑定
        observable.addObserver(this);
    }

    @Override
    public void update(Observable observable, Object o) {
        if (observable instanceof Subject) {
            System.out.println("OneObservable == " + ((Subject) observable).getStatue());
        }
    }
}

/**
 * @author GerryRun
 * @date 2020/9/21 15:02.
 * @email gerryin@163.com
 * @desc 观察者 二号
 */
public class TwoObserver implements Observer {

    public TwoObserver(Observable observable) {

        //与被观察者绑定
        observable.addObserver(this);
    }

    @Override
    public void update(Observable observable, Object o) {

        if (observable instanceof Subject) {
            System.out.println("TwoObserver == " + ((Subject) observable).getStatue());
            //模拟通知过程中发生错误的情况
//            throw new RuntimeException(" throw error message in twoObserver  ");
        }
    }
}
  • 使用:
/**
 * @author GerryRun
 * @date 2020/9/21 15:01.
 * @email gerryin@163.com
 * @desc 测试类
 */
public class TestMainClass {
    public static void main(String[] args) {
        Subject subject = new Subject();
        new OneObserver(subject);
        new TwoObserver(subject);
        new OneObserver(subject);
        new OneObserver(subject);

        subject.setStatue(100);
    }
}
  • 执行main方法结果:
Task :lib_proxytest:TestMainClass.main()
OneObservable == 100
OneObservable == 100
TwoObserver == 100
OneObservable == 100

Android小白和Java小白的二十四种设计模式学习记录。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值