一个demo让你彻底搞懂观察者模式
来源:互联网 发布:周春芽绿狗 知乎 编辑:程序博客网 时间:2024/06/06 00:59
介绍
观察者模式也被称为发布-订阅(Publish/Subscribe)模式,它属于行为型模式的一种。观察者模式定义了一种一对多的依赖关系,一个主题对象可被多个观察者对象同时监听。当这个主题对象状态变化时,会通知所有观察者对象并作出相应处理逻辑。
UML
观察者模式定义了四种角色:抽象主题、具体主题、抽象观察者、具体观察者。
- 抽象主题(Subject):该角色是一个抽象类或接口,定义了增加、删除、通知观察者对象的方法。
- 具体主题(ConcreteSubject):该角色继承或实现了抽象主题,定义了一个集合存入注册过的具体观察者对象,在具体主题的内部状态发生改变时,给所有注册过的观察者发送通知。
- 抽象观察者(Observer):该角色是具体观察者的抽象类,定义了一个更新方法。
- 具体观察者(ConcrereObserver):该角色是具体的观察者对象,在得到具体主题更改通知时更新自身的状态。
实现代码
抽象观察者(Observer)接口
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<Observer> 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,以便对它有更加深刻的理解,觉得这篇文章有用的话,可以点个赞哦~
GitHub的示例项目链接地址:ObserverPatternDemo
1 0
- 一个demo让你彻底搞懂观察者模式
- 一个故事让你彻底搞懂Https
- 让你彻底搞懂offset
- 用造小人让你彻底搞懂什么是建造者设计模式
- 看完让你彻底搞懂Websocket原理
- 看完让你彻底搞懂Websocket原理
- 看完让你彻底搞懂Websocket原理
- 一篇文章让你彻底搞懂Material Design
- 看完让你彻底搞懂Websocket原理
- 看完让你彻底搞懂Websocket原理
- 看完让你彻底搞懂Websocket原理
- 看完让你彻底搞懂Websocket原理
- 看完让你彻底搞懂Websocket原理
- 看完让你彻底搞懂Websocket原理
- 看完让你彻底搞懂Websocket原理
- 看完让你彻底搞懂Websocket原理
- 看完让你彻底搞懂Websocket原理
- 看完让你彻底搞懂Websocket原理
- 批量梯度下降算法BGD,小批量梯度下降法MBGD,随机梯度下降算法SGD的比较
- 小波的秘密8_图像处理应用:图像降噪
- Android 发送验证码倒计时常用的两种办法
- 代理模式
- Error:Execution failed for task ':app:resolveDebugDependencies'. > Could not initialize class com.an
- 一个demo让你彻底搞懂观察者模式
- 如何删除C++容器中的值
- 小波的秘密9_图像处理应用:图像增强
- PHP获取今日、本周、本月、本年初始(凌晨)时间戳的方法
- C++ 运算符重载
- Linux 改写rm命令,让删除编程备份
- ESB v6.5.1,ESB Server MQ服务启动失败--启动报java.net.UnknownHostException: bogon: bogon
- lintcode(247)线段树查询 II
- genymotion安卓模拟器