概念:

  • 建立一种对象与对象之间的联系,一个对象发生改变的时候自动通知其他对象做出反应.

观察目标:

  • 发生改变的对象(可以对应多个观察者,多个观察者之间没有联系,同时可根据需要增删观察者)

观察者:

  • 被通知的对象

名词:

Subject:目标

  • Subject把所有对观察者对象的引用保存在一个聚集(比如ArrayList对象)中,每个Subject都可以有任何数量的观察者。Subject提供一个接口,可以增加和删除观察者对象,Subject又叫做被观察者(Obserbable)

ConcreteSubject:具体目标

  • 将有关状态存入ConcreteSubject;在ConcreteSubject的内部状态改变时,给所有登记过的观察者发送通知。ConcreteSubject又叫做具体被观察者(Concrete Observable)

Observer:观察者

  • 为所有的ConcreteObserver定义一个接口,在得到Subject的通知时更新自己,这个接口叫做更新接口

ConcreteObserver:具体观察者

  • 存储与Subject的状态自恰的状态。ConcreteObserver实现Observer所要求的更新接口,以便使本身的状态与Subject的状态相互协调。如果需要,ConcreteObserver可以保持一个指向ConcreteSubject的引用

实现:

模型:

  • 观察者模式使用Subject、Observer和Client三个类。
    • Subject:
      • 带有绑定观察者到Client的方法
      • 带有从Client解绑观察者的方法

实例:

创建Subjcet:

  • 创建一个Subject管理观察者和被观察者之间的关系
        public abstract class Subject {
            /**
             * 用来保存注册的观察者对象
             */
            public static List<Observer> OBSERVERS_LIST = new ArrayList<>();
            /**
             * 注册观察者对象
             *
             * @param observer 观察者对象
             */
            public static void attach(Observer observer) {
                OBSERVERS_LIST.add(observer);
            }
            /**
             * 删除观察者对象
             *
             * @param observer 观察者对象
             */
            public static void dettach(Observer observer) {
                OBSERVERS_LIST.remove(observer);
            }
            /**
             * 通知所有注册的观察者对象
             */
            public void notifyAllObservers(int progress) {
                for (int i = 0; i < OBSERVERS_LIST.size(); i++) {
                    Observer observer = OBSERVERS_LIST.get(i);
                    observer.updateProgress(progress);
                }
            }
        }

创建Observer类:

  • Obeserver可以是一个接口,只需要有一个用于回调的方法就可以了
        public interface Observer {
            void updateProgress(int progress);
        }

创建ConcreteSubject的实例:

  • 下载进程,它只负责下载,View的显示交给观察者进行更新,它负责通知观察者目前下载进度就行
        public class DownLoadingComponent extends Subject implements Runnable {
            @Override
            public void run() {
                for (int i = 0; i < 100; i++) {
                    SystemClock.sleep(300);
                    progressChange(i);
                }
            }
            private int progress;
            /**
             * 模拟正在下载,进度正在更新
             *
             * @param progress
             */
            public void progressChange(int progress) {
                this.progress = progress;
                System.out.println("后台下载进度" + progress);
                notifyAllObservers(progress);
            }
        }

创建ConcreteObserver实例:

  • 前台显示progress的页面
        public class MainActivity extends AppCompatActivity implements Observer{
            @Override
            public void updateProgress(int progress) {
                System.out.println("我是MainActivity,在更新进度" + progress);
                mProgressView.setProgress(progress);
            }
        }
  • 被遮挡但是能够看到进度条的页面
        public class DetailDialogActivity extends Activity implements Observer {
            @Override
            public void updateProgress(int progress) {
                System.out.println("我是DialogActivity,在更新进度" + progress);
                mProgressView.setProgress(progress);
            }
        }

Demo实例:

img


 评论