首页 / 设计模式 / java设计模式之观察者模式
java设计模式之观察者模式
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java设计模式之观察者模式,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4946字,纯文字阅读大概需要8分钟。
内容图文
![java设计模式之观察者模式](/upload/InfoBanner/zyjiaocheng/850/8aa18d41a27b47178d2f2382578db7b0.jpg)
一、什么是观察者模式
观察者模式定义了对象之间一对多的关系, 当一个对象(被观察者)的状态改变时, 依赖它的对象都会收到通知。可以应用到发布——订阅, 变化——更新这种业务场景中。观察者和被观察者之间用松耦合的方式, 被观察者不知道观察者的细节, 只知道观察者实现了接口。事件驱动模型更加灵活,但也是付出了系统的复杂性作为代价的,因为我们要为每一个事件源定制一个监听器以及事件,这会增加系统的负担。
观察者模式的核心是先分清角色、定位好观察者和被观察者、他们是多对一的关系。实现的关键是要建立观察者和被观察者之间的联系、比如在被观察者类中有个集合是用于存放观察者的、当被检测的东西发生改变的时候就要通知所有观察者。在观察者的构造方法中将被观察者传入、同时将本身注册到被观察者拥有的观察者名单中、即observers这个list中。
二、观察者模式优点
(1)抽象主题只依赖于抽象观察者
(2)观察者模式支持广播通信
(3)观察者模式使信息产生层和响应层分离
三、观察者模式缺点
(1)如一个主题被大量观察者注册,则通知所有观察者会花费较高代价
(2)如果某些观察者的响应方法被阻塞,整个通知过程即被阻塞,其它观察者不能及时被通知
四、观察者模式实例demo----动态计时器
(1)过程说明
关于动态计时器,这里的功能就是可以轻松添加一个或是移除一个计时器。实例里模拟的是倒计时。
我们可以让其存在一个永远不变的量,那就是真实的时间。这个真实的时间T_S可以是使用System.currentTimeMillis()获得时间戳,也可以是一个相对的时间(时间戳本身就是相对时间)。我们把这个“真实”的,永远存在着的时间看成是一个主题(被观察者),可以被不同的观察者进行订阅。而这里的观察者就是我们所说的计时器T_O。
我们可以让T_S在每隔一个时间单位就发布一个消息,即向其所有的订阅者(观察者)说明此时时间已经改变了。订阅者们就可以做出相应的更新操作。我们可以从图-2中看到这个过程。
(2)代码实现
主题模块
我们的主题对象需要有2个基本操作,注册新的观察者、更新通知。这里我增加了一个新的操作,那就是当我们的计时器倒数结束时,我们就把这个观察者计时器从主题的观察者列表中移除。
接口实现如下(TimerSubject.java):
public interface TimerSubject {
/**
* 为新的观察者实现注册服务
*
* @param o
* 观察者
*/
public void registerObserver(TimerObserver o);
/**
* 移除某一个观察者对象
*
* @param o
* 观察者
*/
public void removeObserver(TimerObserver o);
/**
* 更新通知所有的观察者主题状态已经改变
*/
public void notifyObservers();
}
主题类(NagaTimer.java)代码如下:
public class NagaTimer implements TimerSubject {
private long mCurrentStamp = 0L;
private List<TimerObserver> mObservers = null;
public NagaTimer() {
if (mObservers == null) {
mObservers = new ArrayList<>();
}
}
@Override
public void registerObserver(TimerObserver o) {
if (mObservers != null) {
mObservers.add(o);
}
}
@Override
public void removeObserver(TimerObserver o) {
if (mObservers == null) {
return;
}
mObservers.remove(o);
}
/**
* 更新通知所有的观察者
*/
@Override
public void notifyObservers() {
if (mObservers == null || mObservers.size() == 0) {
return;
}
for (int i = 0; i < mObservers.size(); i++) {
CountDownTimer countDownTimer = (CountDownTimer)mObservers.get(i);
if (countDownTimer.isDone()) {
removeObserver(mObservers.get(i));
} else {
countDownTimer.update(mCurrentStamp);
}
}
}
private void measurementsChanged() {
notifyObservers();
}
public void setMeasurements(long currentStamp) {
mCurrentStamp = currentStamp;
measurementsChanged();
}
}
观察者模块
作为观察者,它可以去根据主题的改变进行一些合理的更新操作。本实例中是时间上的倒数。所以需要有一个更新操作和展示操作。
接口实现(TimerObserver.java):
public interface TimerObserver {
/**
* 主题对象只做一件事情,就是更新当前时间
*
* @param stamp
*/
public void update(long stamp);
}
接口实现(TimerDisplayable.java):
public interface TimerDisplayable {
public void display();
}
观察者(CountDownTimer.java):
public class CountDownTimer implements TimerObserver, TimerDisplayable {
private String mName;
private long mStartStamp;
private long mCountdownStamp;
private long mCurrentStamp = 0L;
public CountDownTimer(String name, long countdown) {
this.mStartStamp = System.currentTimeMillis();
this.mName = name;
this.mCountdownStamp = countdown;
}
@Override
public void display() {
if (mCurrentStamp - mStartStamp <= mCountdownStamp) {
System.out.println(getName() + "还剩" + ((mCountdownStamp - (mCurrentStamp - mStartStamp)) / 1000) + "s");
}
}
@Override
public void update(long stamp) {
mCurrentStamp = stamp;
display();
}
public boolean isDone() {
if (mCurrentStamp - mStartStamp >= mCountdownStamp) {
return true;
}
return false;
}
public String getName() {
return mName;
}
}
运行结果如下:
GitHub源码下载:
https://github.com/William-Hai/DesignPatternCollections
内容总结
以上是互联网集市为您收集整理的java设计模式之观察者模式全部内容,希望文章能够帮你解决java设计模式之观察者模式所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。