一、简述:
生活中的观察者模式:
还记得警匪片上,匪徒们是怎么配合实施犯罪的吗?一个团伙在进行盗窃的时候,总有一两个人在门口把风——如果有什么风吹草动,则会立即通知里面的同伙紧急撤退。也许放风的人并不一定认识里面的每一个同伙;而在里面也许有新来的小弟不认识这个放风的。但是这没什么,这个影响不了他们之间的通讯,因为他们之间有早已商定好的暗号。
呵呵,上面提到的放风者、偷窃者之间的关系就是观察者模式在现实中的活生生的例子。
观察者模式简介:
观察者(Observer)模式又名发布-订阅(Publish/Subscribe)模式。GOF给观察者模式如下定义:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
观察者模式完美的将观察者和被观察者分离开来,在模块之间划定了清晰的界限,提高了程序的可维护性和重用性。
二、观察者模式的组成
①抽象主题角色:把所有对观察者对象的引用保存在一个集合中,每个抽象主题角色都可以有任意数量的观察者。抽象主题提供一个接口,可以增加和删除观察者角色。一般用一个抽象类和接口来实现。
②抽象观察者角色:为所有具体的观察者定义一个接口,在得到主题的通知时更新自己。
③具体主题角色:在具体主题内部状态改变时,给所有登记过的观察者发出通知。具体主题角色通常用一个子类实现。
④具体观察者角色:该角色实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态相协调。通常用一个子类实现。如果需要,具体观察者角色可以保存一个指向具体主题角色的引用。
三、Android中应用观察者模式实例
两个Activity之间的通信可以擦用Bundle、接口回调、利用广播的形式,再或者利用系统总线EventBus,那么现在我们还可以利用观察者模式进行通信。本案例的大致是这样:在SecondActivity中监听一个Button是否被触发,其一旦被触发就向观察者发送消息,MainActivity就是一个观察者,当MainActivity接收到消息之后吐司消息内容并更新UI。
效果图如下:
先来看一下抽象Subject代码:
具体的ConcreteSubject代码如下:
抽象Observer代码如下:
具体的Observer代码
我们队SecondActivity中的Button进行监听,代码如下:
完整Demo的下载路径:Android观察者模式demo
生活中的观察者模式:
还记得警匪片上,匪徒们是怎么配合实施犯罪的吗?一个团伙在进行盗窃的时候,总有一两个人在门口把风——如果有什么风吹草动,则会立即通知里面的同伙紧急撤退。也许放风的人并不一定认识里面的每一个同伙;而在里面也许有新来的小弟不认识这个放风的。但是这没什么,这个影响不了他们之间的通讯,因为他们之间有早已商定好的暗号。
呵呵,上面提到的放风者、偷窃者之间的关系就是观察者模式在现实中的活生生的例子。
观察者模式简介:
观察者(Observer)模式又名发布-订阅(Publish/Subscribe)模式。GOF给观察者模式如下定义:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
观察者模式完美的将观察者和被观察者分离开来,在模块之间划定了清晰的界限,提高了程序的可维护性和重用性。
二、观察者模式的组成
①抽象主题角色:把所有对观察者对象的引用保存在一个集合中,每个抽象主题角色都可以有任意数量的观察者。抽象主题提供一个接口,可以增加和删除观察者角色。一般用一个抽象类和接口来实现。
②抽象观察者角色:为所有具体的观察者定义一个接口,在得到主题的通知时更新自己。
③具体主题角色:在具体主题内部状态改变时,给所有登记过的观察者发出通知。具体主题角色通常用一个子类实现。
④具体观察者角色:该角色实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态相协调。通常用一个子类实现。如果需要,具体观察者角色可以保存一个指向具体主题角色的引用。
三、Android中应用观察者模式实例
两个Activity之间的通信可以擦用Bundle、接口回调、利用广播的形式,再或者利用系统总线EventBus,那么现在我们还可以利用观察者模式进行通信。本案例的大致是这样:在SecondActivity中监听一个Button是否被触发,其一旦被触发就向观察者发送消息,MainActivity就是一个观察者,当MainActivity接收到消息之后吐司消息内容并更新UI。
效果图如下:
先来看一下抽象Subject代码:
/**
* 类描述:抽象的Subject
* Created by lizhenya on 16/1/02.
*/
public interface Subject {
void register(Observer observer);
void unregister(Observer observer);
void notifyData(String message);
}
具体的ConcreteSubject代码如下:
/**
* 类描述:具体的Subject
* Created by lizhenya on 16/1/02.
*/
public class ConcreteSubject implements Subject {
//存储Observer实例的Arraylist
private List<Observer> observers = new ArrayList<>();
private static final Object Mutex = new Object();
private static volatile ConcreteSubject concreteSubject = null;
private ConcreteSubject() {
}
//单例模式
public static ConcreteSubject getDefault() {
if (concreteSubject == null) {
synchronized (Mutex) {
if (concreteSubject == null) {
concreteSubject = new ConcreteSubject();
}
}
}
return concreteSubject;
}
@Override
public void register(Observer observer) {
observers.add(observer);
}
@Override
public void unregister(Observer observer) {
if (observers.contains(observer)) {
observers.remove(observer);
}
}
@Override
public void notifyData(String message) {
for (Observer observer : observers) {
observer.onDataChangedEvent(message);
}
}
}
抽象Observer代码如下:
/**
* 类描述:抽象的Observer
* Created by lizhenya on 16/1/02.
*/
public interface Observer {
void onDataChangedEvent(String message);
}
具体的Observer代码
/**
* 实现了Observer接口成为具体的观察者
*/
public class MainActivity extends Activity implements Observer {
private TextView txt;
private Button btn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//将观察者注册到Subject中
ConcreteSubject.getDefault().register(this);
initViews();
}
/**
* 方法描述:初始化布局组件
*/
private void initViews() {
txt = (TextView) findViewById(R.id.txt);
btn = (Button) findViewById(R.id.btn_main);
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this,
SecondActivity.class);
startActivity(intent);
}
});
}
@Override
public void onDataChangedEvent(String message) {
txt.setText(message);
Toast.makeText(MainActivity.this, "MainActivity接到了消息===》" + message, Toast.LENGTH_SHORT).show();
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.e("TAG","反注册");
//反注册
ConcreteSubject.getDefault().unregister(MainActivity.this);
}
}
我们队SecondActivity中的Button进行监听,代码如下:
/**
* @author lizhenya
* @time 2016年1月02日
* @类描述:
*/
public class SecondActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second_activity);
initViews();
}
/**
* @方法描述:初始化布局组件
* @author lizhenya
*/
private void initViews() {
Button btn = (Button) findViewById(R.id.btn);
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//事件被触发:发布消息
ConcreteSubject.getDefault().notifyData("SecondActivity中的button按钮被触发了!!!!!!");
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
}
}
完整Demo的下载路径:Android观察者模式demo