一个简单的demo彻底搞懂观察者模式
介绍
观察者模式也被称为发布-订阅(Publish/Subscribe)模式,它属于行为型模式的一种。观察者模式定义了一种一对多的依赖关系,一个主题对象可被多个观察者对象同时监听。当这个主题对象状态变化时,会通知所有观察者对象并作出相应处理逻辑。
UML
文章图片
观察者模式UML 观察者模式定义了四种角色:抽象主题、具体主题、抽象观察者、具体观察者。
- 抽象主题(Subject):该角色是一个抽象类或接口,定义了增加、删除、通知观察者对象的方法。
- 具体主题(ConcreteSubject):该角色继承或实现了抽象主题,定义了一个集合存入注册过的具体观察者对象,在具体主题的内部状态发生改变时,给所有注册过的观察者发送通知。
- 抽象观察者(Observer):该角色是具体观察者的抽象类,定义了一个更新方法。
- 具体观察者(ConcrereObserver):该角色是具体的观察者对象,在得到具体主题更改通知时更新自身的状态。
public interface Observer {public void update(String msg, TextView tv);
}
具体观察者(Person)类
public class Person implements Observer {// 用户名
private String name;
public Person(String name) {
this.name = name;
}@Override
public void update(String msg, TextView tv) {
tv.setText(tv.getText()+name+":"+ msg +"\n");
}}
抽象主题(Subject)接口
public interface Subject {
/**
* 增加观察者
* @param observer
*/
public void attach(Observer observer);
/**
* 删除观察者
* @param observer
*/
public void detach(Observer observer);
/**
* 通知观察者
*/
public void notify(String message, TextView v);
}
具体主题(XiaosongSubject)类
public class XiaosongSubject implements Subject {//用于保存订阅了小嵩的博客的用户
private List mPersonList = new ArrayList<>();
@Override
public void attach(Observer observer) {
mPersonList.add(observer);
}@Override
public void detach(Observer observer) {
mPersonList.remove(observer);
}@Override
public void notify(String message, TextView tv) {
for (Observer observer : mPersonList) {
observer.update(message,tv);
}
}
}
MainActivity类
public class MainActivity extends AppCompatActivity implements View.OnClickListener{private Person pMing,pQing,pLiang;
private XiaosongSubject mSubject;
private TextView tv_output;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initEvent();
}private void initView() {findViewById(R.id.btn_add_one).setOnClickListener(this);
findViewById(R.id.btn_add_two).setOnClickListener(this);
findViewById(R.id.btn_add_three).setOnClickListener(this);
findViewById(R.id.btn_notify).setOnClickListener(this);
findViewById(R.id.btn_delete).setOnClickListener(this);
tv_output = (TextView)findViewById(R.id.tv_output);
}private void initEvent() {
//创建被观察者(具体主题)
mSubject = new XiaosongSubject();
}@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btn_add_one://注册观察者 小明
if (pMing==null){
pMing = new Person("小明");
mSubject.attach(pMing);
Toast.makeText(this,"小明关注了我",Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(this,"小明已关注我了,不能再重复操作",Toast.LENGTH_SHORT).show();
}
break;
case R.id.btn_add_two://注册观察者 小琴
if (pQing==null){
pQing = new Person("小琴");
mSubject.attach(pQing);
Toast.makeText(this,"小琴关注了我",Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(this,"小琴已关注我了,不能再重复操作",Toast.LENGTH_SHORT).show();
}
break;
case R.id.btn_add_three://注册观察者 阿亮
if (pLiang==null){
pLiang = new Person("阿亮");
mSubject.attach(pLiang);
Toast.makeText(this,"阿亮关注了我",Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(this,"阿亮已关注我了,不能再重复操作",Toast.LENGTH_SHORT).show();
}
break;
case R.id.btn_notify://主题(被观察者)更新了内容,通知所有观察者
tv_output.setText("");
mSubject.notify("小嵩更新微博啦~ 快来看看吧", tv_output);
break;
case R.id.btn_delete://注销观察者 小明
if (pMing!=null){
mSubject.detach(pMing);
pMing = null;
}if (pQing!=null){//注销观察者 小琴
mSubject.detach(pQing);
pQing = null;
}if (pLiang!=null){//注销观察者 阿亮
mSubject.detach(pLiang);
pLiang = null;
}break;
default:
break;
}
}
}
总结 在Android中,有很多场景使用了观察者模式,比如Android的源码里:OnClickListener、ContentObserver、android.database.Observable等;还有第三方开源库EventBus、RxJava、RxAndroid等。具体可阅读它们的源码去理解和体会。这里我写了一个简单的demo,以便对它有更加深刻的理解,觉得这篇文章有用的话,可以点个赞哦~
【一个简单的demo彻底搞懂观察者模式】GitHub的示例项目链接地址:ObserverPatternDemo
这里写图片描述
推荐阅读
- 热闹中的孤独
- JAVA(抽象类与接口的区别&重载与重写&内存泄漏)
- 放屁有这三个特征的,请注意啦!这说明你的身体毒素太多
- 一个人的旅行,三亚
- 布丽吉特,人生绝对的赢家
- 慢慢的美丽
- 尽力
- 一个小故事,我的思考。
- 家乡的那条小河
- 《真与假的困惑》???|《真与假的困惑》??? ——致良知是一种伟大的力量