文章目录
- 1、观察者模式简介
- 2、观察者模式的定义
- 3、观察者模式的使用场景
- 4、观察者模式的UML 类图
- 5、观察者模式的简单实现
- 1)文件结构
- 2)DevTechFrontier 被观察者 文件
- 3) Coder 观察者 文件
- 4) MainActivity 文件
- 5、打印 log
- 6、运用思路
1、观察者模式简介
观察者模式使用最多的地方是GUI系统,这个模式最多的作用就是解耦。
2、观察者模式的定义
定义对象间一对多的模式,使得没当一个对象改变状态,则所有依赖它的对象都会得到通知并更新。
3、观察者模式的使用场景
1)关联行为场景
2)事件多级触发场景
3)跨系统的消息交互场景,如消息队列、事件总线等
4、观察者模式的UML 类图
- Subject: 抽象主题,也是被观察者角色,抽象主题角色把所有观察者对象的引用保存在一个集合里,每个主题都可以有任意数量的观察者,抽象主题提供一个接口,可以增加和删除观察者对象。
2)ConcreteSubject :具体主题,该角色将有关对象状态存入具体观察者对象,在具体主题的内部状态发生改变时,给所有注册过的观察者发送通知,具体主题角色又叫做具体被观察者角色。
3)Observer: 抽象观察者,该角色是观察者的一个抽象类,它定义了一个抽象接口,使得在得到主题更新时提示自己。
4)ConcreteObserver: 具体的观察者,该角色实现抽象观察者角色,定义更新接口,以便在主题状态发生变化时,更新自身状态。
5、观察者模式的简单实现
我们模拟一个后台更新数据,前台更新相关操作的,观察者模式。
1)文件结构
1) DevTechFrontier 是我们的 被观察者,继承 Observable 类
2)Coder 是我们的 观察者 ,继承 Observer 类
3)MainActivity 主要是 对 观察者 ,被观察者的 实体化 ,同时初始化数据
2)DevTechFrontier 被观察者 文件
package com.example.lum.myobserver;
import android.util.Log;
import java.util.Observable;
/**
* Created by lum on 2018/11/25.
*/
/*
* DevTechFrontier 这个是被观察者者角色,当它更新时,所有的观察者都会接到相应的通知
*
* */
public class DevTechFrontier extends Observable {
private String TAG = "DevTechFrontier: ";
public void postNewPublication(String content) {
//······可在此处理后台数据
Log.i(TAG,"被观察者 更新有消息更新");
//标记状态 或者内容 发生改变
setChanged();
//通知所有观察者
notifyObservers(content);
}
}
3) Coder 观察者 文件
package com.example.lum.myobserver;
import android.util.Log;
import java.util.Observable;
import java.util.Observer;
/**
* Created by lum on 2018/11/25.
*/
//程序员是观察者
public class Coder implements Observer {
private String TAG = "Coder: ";
public String name;
public Coder(String name) {
this.name = name;
}
@Override
public void update(Observable o, Object arg) {
Log.i(TAG,"HI, " + name + " DevTechFrontier 更新啦, 内容是: " + arg);
}
@Override
public String toString () {
return "码农: " + name ;
}
}
4) MainActivity 文件
package com.example.lum.myobserver;
import android.support.v7.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);
//被观察者角色
DevTechFrontier devTechFrontier = new DevTechFrontier();
//观察者, 创建三个观察者
Coder coder_1 = new Coder("code_1");
Coder coder_2 = new Coder("code_2");
Coder coder_3 = new Coder("code_3");
//将观察者注册到 可观察者对象的观察者列表里
devTechFrontier.addObserver(coder_1);
devTechFrontier.addObserver(coder_2);
devTechFrontier.addObserver(coder_3);
//被观察者 发布消息
devTechFrontier.postNewPublication("被观察者发布新的 消息");
}
}
5、打印 log
我们可以看到被观察者改变了数据,注册的 观察者 都会在update 函数里 接收到更新
(1) ObServer 和 Observable 是JDK 的内置类型,可见观察者模式是非常重要的。
(2) 这里的Observer 是抽象的观察者角色,Coder是具体的观察者角色。
(3)Observable 对应的是抽象主题角色, DevTechFrontier 是 具体的主题角色。
(4)当 DevTechFrontier 有更新时,会遍历所有观察者(coder), 然后给这些观察者 发布更新的消息,这样就达到一对多的更新。
6、运用思路
1)一个类 继承 ObServer 作为 观察者
2)一个类继承 Observable 作为被观察者
3)将观察者 注册到 被观察者 里
4)当调用到被观察者更新的函数,就会出发观察者里的update函数
5)两个类的数据传递
被观察者 : notifyObservers(content);
观察者:update(Observable o, Object arg) ;
文献参考:
Android 源码设计模式解析与实战 第二版
本人郑重声明,本博客所编文章、图片版权归权利人持有,本博只做学习交流分享所用,不做任何商业用途。访问者可將本博提供的內容或服务用于个人学习、研究或欣赏,不得用于商业使用。同時,访问者应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人的合法权利;如果用于商业用途,须征得相关权利人的书面授权。若文章、图片的原作者不愿意在此展示內容,请及时通知在下,將及时予以刪除。