您的位置:首页 > 其它

观察者设计模式

2019-07-15 11:26 99 查看

观察者设计模式:

百度百科定义:
观察者模式(有时又被称为模型(Model)-视图(View)模式、源-收听者(Listener)模式或从属者模式)是软件设计模式的一种。在此模式中,一个目标物件管理所有相依于他的观察者物件,并且在他本身的状态改变时主动发出通知。这通常投过呼叫各种观察者所提供的方法来实现。此种模式通常被用来实现时间处理系统。

思维导图:

什么是观察者设计模式:
观察者模式(Observer)是软件设计模式的一种,定义了对象之间一种一对多的关系,也就是当一个对象数据发生变化时,会通知与之依赖的其他对象,以相应其数据变化,这种当目标对象数据发生变化时,与之对应的观察者对象数据随之发生变化的,具有一对多通知关系的设计模式叫做观察者设计模式。

关键概念理解:
观察者:指观察者对象,也就是消息的订阅者;
被观察者:指要观察的目标对象,也就是消息的发布者;

通知观察者的方式:
推:消息以类似广播的形式通知观察者,观察者只能被动、无条件的接受;
:接受到被观察者的通知,可以自主决定获取消息;

两种方式的比较:
1)推模型时假定主题对象知道观察者需要的数据;而拉模型是主题对象不知道观察者具体需要什么数据,没有办法的情况下,干脆把自身传递给观察者,让观察者自己去按需要取值。
2)推模型可能会使得观察者对象难以服用,因为观察者的updata()方法是按需要定义的参数,可能无法兼顾没有考虑到的使用情况。这就意味着出现新情况的时候,就可能提供新的updata()方法,或者是干脆重新实现观察者;而拉弄下就不会造成这样的情况,以为拉模型下,updata()方法的参数是主题对象本身,这剧本上是主题对象能传递的最大数据集合了,基本上可以适应各种情况的需要。

  1. 手写观察者模式:

首先创建被观察者,具体如下:

/**
* 观察者要观察的目标对象
* @author jzman
*/
public abstract class Subject {
protected ArrayList<Observer> observerList = new ArrayList<>();
//表示观察者对目标对象(被观察者)开始观察
public void registerObserver(Observer obs) {
observerList.add(obs);
}
//表示取消某观察者对目标对象(被观察者)的观察
public void unRegisterObserver(Observer obs) {
observerList.remove(obs);
}
//当目标对象(被观察者)的状态发生变化时,及时更新观察者的状态
public void notifyAllObserver(){
for (Observer observer : observerList) {
observer.update(this);
}
}
}

创建具体的被观察者,具体如下:

/**
* 具体的目标对象(被观察者)
* @author jzman
*/
public class ConcreteSubject extends Subject{
private int state;
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
//当数据发生变化时通知其他的观察者
notifyAllObserver();
}
}

然后,为了统一方便,定义观察者接口,具体如下:

/**
* 观察者统一接口
* @author jzman
*/
public interface Observer {
void update(Subject subject);
}

然后,创建具体的观察者,具体如下:

/**
* 具体的观察者
* @author jzman
*/
public class ConcreteObserver implements Observer{
private int state;
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
@Override
public void update(Subject subject) {
//获取目标对象的数据变化,同时更新当前观察者
ConcreteSubject concreteSubject = (ConcreteSubject)subject;
state = concreteSubject.getState();
}
}

最后,测试观察者设计模式,具体如下:

/**
* Main
* @author jzman
*/
public class Client {
public static void main(String[] args) {
//创建具体的目标对象(被观察者)
ConcreteSubject concreteSubject = new ConcreteSubject();
//创建多个具体的观察者
ConcreteObserver obs1 = new ConcreteObserver();
ConcreteObserver obs2 = new ConcreteObserver();
ConcreteObserver obs3 = new ConcreteObserver();
//让观察者观察目标对象(被观察者)的数据变化
concreteSubject.observerList.add(obs1);
concreteSubject.observerList.add(obs2);
concreteSubject.observerList.add(obs3);
//改变某个目标对象(被观察者)的数据
concreteSubject.setState(10);
//观察者数据是否与被观察者数据变化一致
System.out.println("观察者obs1:"+obs1.getState());
System.out.println("观察者obs2:"+obs2.getState());
System.out.println("观察者obs3:"+obs3.getState());
}
}

执行结果如下:

观察者obs1:10
观察者obs2:10
观察者obs3:10

通过对目标对象数据的改变,更显了与之相对应的观察者的数据,实现了消息的订阅和发送。

2.Java API 提供的观察者设计模式
Java API 提供的观察者设计模式主要通过Observer 和 Observeable 来实现,首先创建一个类继承Observeable 作为被观察者,具体如下:

/**
* 被观察者(目标对象)
* @author jzman
*/
public class ConcreteSubject extends Observable{
private int state;
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
//表示数据已经发生变化
setChanged();
//具体的目标对象数据变化的时候通知观察者
notifyObservers(state);
}
}

然后,创建一个类继承Observer 作为观察者,具体如下:

/**
* 观察者
* @author jzman
*/
public class ConcreteObserver implements Observer{
private int state;
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
@Override
public void update(Observable arg0, Object arg1) {
ConcreteSubject concreteSubject = (ConcreteSubject) arg0;
//根据目标对象(被观察者)的数据变化更新当前观察者的数据
this.state = concreteSubject.getState();
}
}

测试观察者设计模式,具体如下:

/**
* 测试观察者设计模式
* @author jzman
*/
public class Client {
public static void main(String[] args) {
ConcreteSubject concreteSubject = new ConcreteSubject();

ConcreteObserver obs1 = new ConcreteObserver();
ConcreteObserver obs2 = new ConcreteObserver();
ConcreteObserver obs3 = new ConcreteObserver();

concreteSubject.addObserver(obs1);
concreteSubject.addObserver(obs2);
concreteSubject.addObserver(obs3);

concreteSubject.setState(100);

System.out.println("观察者obs1:"+obs1.getState());
System.out.println("观察者obs2:"+obs2.getState());
System.out.println("观察
3ff7
者obs3:"+obs3.getState());
}
}

执行结果如下:

观察者obs1:100
观察者obs2:100
观察者obs3:100

观察者设计模式的优缺点:

优点:****观察者与被观察者抽象耦合,可定义一种稳定的消息出发机制。

缺点:如果被观察者有多个间接的观察者,消息的传递将消耗更多时间,如果观察者与被观察之间循环依赖,最终会导致系统崩溃。

使用场景:

如游戏、聊天等过程中消息的从服务端转发给客户端的过程。
Android中的广播机制以及ListView 中通知数据发生变化时也是观察者设计模式。
订阅相关的系统,如订阅的主题有更新,订阅者就会同步订阅的文章。

转载地址:https://blog.csdn.net/jzman/article/details/80045184

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: