Observer和Observable-观察者设计模式

观察者模式Observer和Observable

简述

观察者模式类广播一对多的模式传递消息,为了直观的解释这个模式,直接手写一个观察者模式的整体代码吧

手写观察者模式

1.创建观察者接口

观察者是来观察变化的,所以,观察者属于数据变更之后被动收到消息做出动作的这个对象,那么,这个接口就是扩展观察者的能力,让其拥有做动作的能力

public interface myObserver {
    void update(myObservable myObservable,Object obj);
}

其实看到这个接口肯定就能想到是观察者继承了接口,然后在变化时,这个接口中的这个update方法被调用了

2.创建被观察者(建议理解为数据,方便弄清楚概念)

根据上述,在变化时,这个接口中的这个update方法被调用了,(暂时简单理解为数据变化了),那么,被观察者首先应该要持有观察者对象,上面说到类似广播,于是是有可能会持有很多个观察者,再考虑到后面需要由观察者调用上面接口中的方法,应该有一个集合储存观察者,这是一部分,接着,观察者应该是被添加进来的,就有添加方法,同样删除的方法,最重要的,得有通知的方法,也就是说,数据变化,数据调通知方法,方法中遍历观察者,调用观察者对象的扩展接口的方法让其拥有做动作的能力(更新状态)
至于加锁什么的在代码中有注释
上代码

package com.example.objecttest;

import java.util.Vector;

public class myObservable {
    //vector是一个线程安全的集合,缺点是速度较慢,它用来储存观察者对象
    private final Vector<myObserver> myObservers;
    private boolean changed = false;

    //构造方法
    public myObservable() {
        myObservers = new Vector<>();
    }

    //添加观察者,这个方法需要加锁
    public synchronized void addObserver(myObserver observer) {
        if (observer == null) {
            throw new NullPointerException("observer is null");
        }
        if (!myObservers.contains(observer)) {
            myObservers.addElement(observer);//按照先后循序一次添加
        }
    }

    //删除观察者
    public synchronized void deleteObserver(myObserver observer) {
        myObservers.remove(observer);
    }

    //删除所有观察者
    public synchronized void deleteAllObserver() {
        myObservers.clear();
    }

    //统计所以得observer
    public synchronized int countAllObservers() {
        return myObservers.size();
    }

    //提供一个方法通知变化观察着
    public void notifyObserver() {
        notifyObserver(null);
    }

    public void notifyObserver(Object o) {
        Object[] observerObject = null;
        //为了防止在通知的时候有新的观察着添加进来而错过
        synchronized (this) {
            //当外部手动添加并改变changed时
            if (!hasChanged()) {
                return;
            }
            //没有改变时
            observerObject = myObservers.toArray();
            clearChanged();
        }
        for (int i = observerObject.length - 1; i >= 0; i--) {
            //逐个遍历观察着,调用upDate方法
            ((myObserver) observerObject[i]).update(this, o);
        }
    }

    private void clearChanged() {
        changed = false;
    }

    private boolean hasChanged() {
        return changed;
    }

    public void setChanged() {
        changed = true;
    }
}

3.使用示例

上代码

创建被观察者

package com.example.objecttest;

//被观察者(数据)
public class Message extends myObservable {
    public void messageHasChanged(String message) {
        setChanged();//这个方法设置进去会使得在notify的时候不会进入if循环走return
        notifyObserver(message);//通知刷新
    }
}

创建观察者

package com.example.objecttest;

import android.util.Log;

import java.util.Observable;
import java.util.Observer;
//观察者实现接口,重写方法,扩展能力
public class Person implements myObserver {

    private String name;

    public Person(String name) {
        this.name = name;
    }

    @Override
    public void update(myObservable myObservable, Object obj) {
        //业务操作
        Log.e("len.hu",name + "收到了" + obj.toString() + "消息");
    }
}

Acitvity中的使用

package com.example.objecttest;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //创建观察者,人观察数据
        Person p1 = new Person("小虎");
        Person p2 = new Person("飘飘");
        Person p3 = new Person("图图");
        Person p4 = new Person("爷爷");

        //创建被观察者,比如说数据
        Message message = new Message();

        //将二者关联起来
        message.addObserver(p1);
        message.addObserver(p2);
        message.addObserver(p3);
        message.addObserver(p4);

        //假设数据变更
        message.messageHasChanged("今天中午吃饭了没有");

    }
}

日志结果打印
在这里插入图片描述
至于这个为什么是倒序,看看上面的代码就好了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值