观察者模式的定义:
定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则依赖于它的对象都会得到通知并被自动更新
观察者模式的使用场景
1.关联行为场景,需要注意的是,关联行为是可以拆分的,而不是组合的关系
2.事件多级触发场景。点击事件
3.跨系统的消息交换场景,如消息队列、事件总线的处理机制
观察者模式的组成
Sunbject:抽象主题,也就是被观察(observable)的角色,抽象主题把所有的观察者对象引用保存到一个集合中,每个主题都可以有任意数量的观察者,抽象主题提供一个接口,可以增加和删除观察者对象
ConcreteSubject:具体主题(被观察者),在具体主题的内部改变时,给所有注册过的观察者发出通知
Observer:抽象观察者,该角色是观察者的抽象类,它定义一个更新接口,在得到被观察者的通知后更新
ConcreteObserver:具体的观察者。
观察者模式的案例
一、直接使用JDK中的内置类型Observer(观察者)和Observable(被观察者)。(个人认为无需讲解。代码程序员都能看懂)
/**
* 被观察者
*
* setChaged()告知数据改变
* notifyObservers()通知观察者
*/
public class MyPerson extends Observable{
private String name;
private int age;
private String sex;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
setChanged();
notifyObservers();
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
setChanged();
notifyObservers();
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
setChanged();
notifyObservers();
}
@Override
public String toString() {
return "MyPerson [name=" + name + ", age=" + age + ", sex=" + sex + "]";
}
}
/**
* 观察者
*/
public class MyObserver implements Observer {
private int id;
private MyPerson myPerson;
public MyObserver(int id){
Log.i("zy","我是观察者---->" + id);
this.id=id;
}
@Override
public void update(Observable o, Object arg) {
Log.i("zy","观察者---->" + id + "得到更新");
this.myPerson= (MyPerson) o;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public MyPerson getMyPerson() {
return myPerson;
}
public void setMyPerson(MyPerson myPerson) {
this.myPerson = myPerson;
}
}
public class MainActivity extends AppCompatActivity {
public static final int MSG_RECEIVED_CODE = 1;
private TextView textContent;
private Button btnAddObserver;
private Button btnChangeData;
private MyPerson observable;
private MyObserver myObserver;
/**
* 观察者集合
*/
private List<MyObserver> myObservers;
private ListView listview;
private int i;
private Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
if (msg.what == MSG_RECEIVED_CODE) {
String code = (String) msg.obj;
textContent.setText(code);
}
else {
MyListAdapter myListAdapter = new MyListAdapter(MainActivity.this,
myObservers);
listview.setAdapter(myListAdapter);
}
};
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnAddObserver = (Button) findViewById(R.id.btn_add_observer);
btnChangeData = (Button) findViewById(R.id.btn_change_data);
listview = (ListView) findViewById(R.id.list);
textContent= (TextView) findViewById(R.id.textContent);
observable = new MyPerson();
myObservers = new ArrayList<MyObserver>();
/**
* 添加观察者
*/
btnAddObserver.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
myObserver=new MyObserver(i);
i++;
observable.addObserver(myObserver);
myObservers.add(myObserver);
handler.sendEmptyMessage(0);
}
});
/**
* 通知更新数据
*/
btnChangeData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
observable.setAge(10+i);
observable.setName("三分"+i);
handler.sendEmptyMessage(0);
}
});
}
}
二、使用自定义的方法实现观察者模式
抽象主题
/**
* 被观察者接口
*/
public interface SubjectListener {
/**
* 注册
* @param observerListener
*/
void add(ObserverListener observerListener);
/**
* 通知
* @param content
*/
void notifyObserver(String content);
/**
* 删除
* @param observerListener
*/
void remove(ObserverListener observerListener);
}
抽象观察者
/**
* 观察者接口
*/
public interface ObserverListener {
/**
* 更新数据
* @param content
*/
void observerUpData(String content);
}
具体主题
/**
*被观察者具体
*/
public class ObserverManager implements SubjectListener{
public static ObserverManager observerManager;
/**
* 观察者集合
*/
public List<ObserverListener>mList=new ArrayList<>();
/**
* 单例模式
* @return
*/
public static ObserverManager getIntance(){
if (null==observerManager){
synchronized (ObserverManager.class){
observerManager=new ObserverManager();
}
}
return observerManager;
}
/**
* 添加观察者
* @param observerListener
*/
@Override
public void add(ObserverListener observerListener) {
mList.add(observerListener);
}
/**
* 通知观察者更新数据
* @param content
*/
@Override
public void notifyObserver(String content) {
for (ObserverListener observerListener:mList){
observerListener.observerUpData(content);
}
}
/**
* 移除观察者
* @param observerListener
*/
@Override
public void remove(ObserverListener observerListener) {
if (mList.contains(observerListener)){
mList.remove(observerListener);
}
}
}
具体观察者,这里我是三个Activity
/**
*第一个
*/
public class OneActivity extends AppCompatActivity implements ObserverListener{
private TextView observerText;
private Button observerButton;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_one);
observerText= (TextView) findViewById(R.id.obser_text);
observerButton= (Button) findViewById(R.id.obser_button);
/**
*点击跳转下个界面
*/
observerButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent=new Intent(OneActivity.this,TwoActivity.class);
startActivity(intent);
}
});
/**
* 注册观察者
*/
ObserverManager.getIntance().add(this);
}
/**
* 数据改变
* @param content
*/
@Override
public void observerUpData(String content) {
Log.i("zy","内容"+content);
observerText.setText(content);
}
}
package com.tdb.wys.observered;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
/**
* 第二个Activity
*/
public class TwoActivity extends AppCompatActivity implements ObserverListener{
private TextView observerText;
private Button observerButton;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_two);
observerText= (TextView) findViewById(R.id.obser_text);
observerButton= (Button) findViewById(R.id.obser_button);
observerButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent=new Intent(TwoActivity.this,ThressActivity.class);
startActivity(intent);
}
});
ObserverManager.getIntance().add(this);
}
@Override
public void observerUpData(String content)
{
Log.i("zy","内容"+content);
observerText.setText(content);
}
}
package com.tdb.wys.observered;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
/**
*第三个Activity
*/
public class ThressActivity extends AppCompatActivity implements ObserverListener{
private TextView observerText;
private Button observerButton;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_thress);
observerText= (TextView) findViewById(R.id.obser_text);
observerButton= (Button) findViewById(R.id.obser_button);
observerButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
/**
*通知被观察者
*/
ObserverManager.getIntance().notifyObserver("改了吗观察者内容");
}
});
ObserverManager.getIntance().add(this);
}
@Override
public void observerUpData(String content) {
Log.i("zy","内容"+content);
observerText.setText(content);
}
}
这个几个Activity的界面都非常简单。一个Button一个TextView,这里我就不贴出来了。在最后一个Activity,使用来通知被观察者然后更新观察者数据。
运行结果:
不会上传视频,只能通过Gif图片显示。图片有点模糊,各位莫见怪。如果有啥不懂。请看