观察者模式
高中的时候,班里有个两个同学太困了,就钻到桌子地下睡觉,结果被班主任抓包,打断了跟拖把,虽然面临高考还能这么淡定也是个人才。 怎么回事呢? 刘某被老师长期罚坐在门外上课!于是郑某每天帮刘某买饭,刘某成为了郑某的眼线,看到班主任来就把他叫起来。这样相安无事过了几天,然而事实证明刘某是靠不住的,今天刘某也睡着了,然后班主任亲自叫醒了刘某,然后带着刘某叫醒了班里熟睡的郑某,这样刘郑二人双双被打,直到拖把杆被打断。最后一个体育生郑dh跑进了中国矿业大学,另一个睡着了没离开又复读了一年! 这不就是观察者模式吗? 你可能认为刘某是观察者,其实郑某才是观察者,他观察刘某的动态,然后做出反馈,有点违背我们平时的理解。啪~ 啪 ~ 啪~!请看下文!
观察者模式又叫做:
脑海中立刻闪现了《Head First设计模式》里讲的:
Publishers + Subscribers = Observer Pattern
他还应该叫发布订阅模式?但是确实不是,之前我混为一谈确实不对!这篇文章比较详细的讲解他们两个区别,并给出了源代码及实例,有兴趣的可以看一下。 发布者订阅者模式到底是个啥?看这!
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态上发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
一个软件系统常常要求在某一个对象的状态发生变化的时候,某些其它的对象做出相应的改变。做到这一点的设计方案有很多,是为了使系统能够易于复用,应该选择低耦合度的设计方案为了使系统能够易于复用,应该选择低耦合度的设计方案。
减少对象之间的耦合有利于系统的复用,但是同时设计师需要使这些低耦合度的对象之间能够维持行动的协调一致,保证高度的协作( Collaboration)。观察者模式是满足这一要求的各种设计方案中最重要的一种。
一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。
一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。
使用面向对象技术,可以将这种依赖关系弱化,从而降低耦合性,避免循环观察形成死锁。
在抽象类里有一个 ArrayList 存放观察者们。
观察者模式(Observer), 定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并自动更新。UML结构图如下:
使用场景:
注意事项
目标和观察者之间的关系:
单向依赖:
触发通知的时机:
相互观察:
通知的顺序
首先定义一个观察者数组,并实现增、删及通知操作。它的职责很简单,就是定义谁能观察,谁不能观察,用Vector是线程同步的,比较安全,也可以使用ArrayList,是线程异步的,但不安全。
public class Subject {
//观察者数组
private Vector<Observer> oVector = new Vector<>();
//增加一个观察者
public void addObserver(Observer observer) {
this.oVector.add(observer);
}
//删除一个观察者
public void deleteObserver(Observer observer) {
this.oVector.remove(observer);
}
//通知所有观察者
public void notifyObserver() {
for(Observer observer : this.oVector) {
observer.update();
}
}
}
public interface Observer {
//更新
public void update();
}
继承Subject类,在这里实现具体业务,在具体项目中,该类会有很多变种。 将有关状态存入具体现察者对象;在具体主题的内部状态改变时,给所有登记过的观察者发出通知。具体主题角色又叫做具体被观察者角色(Concrete Observable)具体主题角色通常用一个具体子类实现。
public class ConcreteSubject extends Subject {
//具体业务
public void doSomething() {
//...
super.notifyObserver();
}
}
具体现察者角色实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态相协调。如果需要,具体现察者角色可以保存一个指向具体主题对象的引用。具体观察者角色通常用一个具体子类实现。
public class ConcreteObserver implements Observer {
@Override
public void update() {
System.out.println("收到消息,进行处理");
}
}
首先创建一个被观察者,然后定义一个观察者,将该被观察者添加到该观察者的观察者数组中,进行测试。
public class Client {
public static void main(String[] args) {
//创建一个主题
ConcreteSubject subject = new ConcreteSubject();
//定义一个观察者
Observer observer = new ConcreteObserver();
//观察
subject.addObserver(observer);
//开始活动
subject.doSomething();
}
}
.NET
中提供了Delegate
与Event
机制,我们可以利用这种机制简化Observer模式。基于.NET简化的观察者模式。举个例子: 那天博主的股票上市了,你们买了我的股票,我的股票涨了跌了得通知你们,我们就按照这个写一个。
package 观察者模式;
public interface Observer {
public void update(Object c);
}
package 观察者模式;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Vector;
public class Subject {
private Vector<Observer> oVector;
public Subject() {
oVector=new Vector<Observer>();
}
public void addObserver(Observer observer) {
this.oVector.add(observer);
}
public void deleteObserver(Observer observer) {
this.oVector.remove(observer);
}
public void notifyObserver() {
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date d = new Date( );
sf.format(d);
for (Observer observer : this.oVector) {
observer.update(d);
}
}
}
package 观察者模式;
public class Share_Observer implements Observer {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void update(Object c) {
System.out.println(name+"已更新股票数据"+c);
}
}
package 观察者模式;
public class Shares_Subject extends Subject {
public void RealTime_Update() {
super.notifyObserver();
}
}
package 观察者模式;
public class Client {
public static void main(String[] args) {
Shares_Subject subject = new Shares_Subject();
Share_Observer observer = new Share_Observer();
observer.setName("张俊浩的A股");
subject.addObserver(observer);
subject.RealTime_Update();
}
}
写在最后: 我叫风骨散人,名字的意思是我多想可以不低头的自由生活,可现实却不是这样。家境贫寒,总得向这个世界低头,所以我一直在奋斗,想
改变我的命运
给亲人好的生活,希望同样被生活绑架的你
可以通过自己的努力改变现状,深知成年人的世界里没有容易二字。目前是一名在校大学生,预计考研,热爱编程,热爱技术,喜欢分享,知识无界,希望我的分享可以帮到你! 如果有什么想看的,可以私信我,如果在能力范围内,我会发布相应的博文! 谢谢大家的阅读!?