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

观察者模式,是一个比较有用的一个设计模式:通俗的讲就是一个被观察者,多个观察者,被观察者发生了变化,会通知观察者,观察者做出各自的事情。
举个例子: 司马光砸缸的典故我想大家都知道。一个小朋友(被观察者)从水缸的外面掉进了水里,于是开始呼救(发出通知),司马光等(观察者)听到这个呼救的时候就做出各种救命的措施()

我们可以看下android自带的源代码:

package java.util;

public class Observable {
    private boolean changed = false;
    private Vector<Observer> obs;

    public Observable() {
        obs = new Vector<>();
    }

    //添加观察者
    public synchronized void addObserver(Observer o) {
        if (o == null)
            throw new NullPointerException();
        if (!obs.contains(o)) {
            obs.addElement(o);
        }
    }

    //删除观察者
    public synchronized void deleteObserver(Observer o) {
        obs.removeElement(o);
    }

    //通知观察者
    public void notifyObservers() {
        notifyObservers(null);
    }

    public void notifyObservers(Object arg) {

        Object[] arrLocal;

        synchronized (this) {
            if (!changed)
                return;
            arrLocal = obs.toArray();
            clearChanged();
        }

        for (int i = arrLocal.length-1; i>=0; i--)
            ((Observer)arrLocal[i]).update(this, arg);
    }


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


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


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


    public synchronized boolean hasChanged() {
        return changed;
    }


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

代码不多!并且结构很简单,也就是添加观察者,删除观察者,通知观察者几个方法。
但是我们的需求多种多样,而源码里只提供了update的方法
所以我们一般根本不去继承Observable

下面代码走起!
假设我们有个下载的任务。我们有多个页面需要监测这个下载的任务:

public class DownLoadManager {
    private Vector<MyObserver> obs = new Vector<>();
    private static final int IS_STARTED = 0;
    private static final int IS_LOADING = 1;
    public static final int IS_OK = 2;
    private int state = 0;
    private int currentNum = 0;

    public interface MyObserver {
        void update(int currentNum);

        void updatestate(int state);
    }

    //添加观察者
    public synchronized void addObserver(MyObserver o) {
        if (o == null)
            throw new NullPointerException();
        if (!obs.contains(o)) {
            obs.addElement(o);
        }
    }

    //删除观察者
    public synchronized void deleteObserver(MyObserver o) {
        obs.removeElement(o);
    }

    //通知更新
    private void notifyObservers() {
        Object[] arrLocal;
        synchronized (this) {
            arrLocal = obs.toArray();
        }
        for (int i = arrLocal.length - 1; i >= 0; i--)
            ((MyObserver) arrLocal[i]).update(currentNum);
    }

    //通知更新状态
    private void notifyState() {
        Object[] arrLocal;
        synchronized (this) {
            arrLocal = obs.toArray();
        }
        for (int i = arrLocal.length - 1; i >= 0; i--)
            ((MyObserver) arrLocal[i]).updatestate(state);
    }

    public void startLoad() {
        new Thread(
                new Runnable() {
                    @Override
                    public void run() {
                        while(currentNum < 100){
                            try {
                                Thread.sleep(200);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                            currentNum ++;
                            notifyObservers();
                            state = IS_LOADING;
                            notifyState();
                        }
                        state = IS_OK;
                        notifyState();
                    }
                }
        ).start();
    }
}

再来个页面监测

package com.myobserver;

public class MainActivity extends AppCompatActivity implements DownLoadManager.MyObserver {

    private TextView tv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        tv = (TextView)findViewById(R.id.textView);
        DownLoadManager manager = new DownLoadManager();
        manager.addObserver(this);
        manager.startLoad();
    }

    @Override
    public void update(final int currentNum) {
        runOnUiThread(
                new Runnable() {
                    @Override
                    public void run() {
                        tv.setText(currentNum+"");
                    }
                }
        );
    }

    @Override
    public void updatestate(int state) {
        if(state == DownLoadManager.IS_OK){
            runOnUiThread(
                    new Runnable() {
                        @Override
                        public void run() {
                            Toast.makeText(MainActivity.this, "下载完成啦", Toast.LENGTH_SHORT).show();
                        }
                    }
            );

        }
    }
}

这里写图片描述
下载完成的提示在屏幕下方,没有截取到哈,大家可以下载代码试试

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值