一、基础简介
1、定义
定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,当主题对象的状态发生改变时,会通知所有观察者对象,使他们能够自动更新自己。观察者模式属于行为型模式。
2、使用场景
当一个对象的改变需要同时改变其他对象,而且它不知道具体有多少对象有待改变时(解耦),可以考虑使用观察者模式。
3、优缺点
优点: 1、观察者和被观察者是抽象耦合的。 2、建立一套触发机制。
缺点: 1、如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。 2、如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。 3、观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。
4、模式结构
- 抽象主题(Subject)角色:也叫抽象目标类,它提供了一个用于保存观察者对象的聚集类和增加、删除观察者对象的方法,以及通知所有观察者的抽象方法。
- 具体主题(Concrete Subject)角色:也叫具体目标类,它实现抽象目标中的通知方法,当具体主题的内部状态发生改变时,通知所有注册过的观察者对象。
- 抽象观察者(Observer)角色:它是一个抽象类或接口,它包含了一个更新自己的抽象方法,当接到具体主题的更改通知时被调用。
- 具体观察者(Concrete Observer)角色:实现抽象观察者中定义的抽象方法,以便在得到目标的更改通知时更新自身的状态。
二、代码实例
1、UML类图
2、Subject 抽象目标类:通知者
package com.mfc.design.观察者模式;
import java.util.ArrayList;
import java.util.List;
/**
* @author MouFangCai
* @date 2019/10/16 10:39
*
* 抽象通知者
*/
public class Subject {
private String subjectName;
private List<Observer> observers = new ArrayList<>();
public void attach(Observer observer) {
observers.add(observer);
}
public void detach(Observer observer) {
observers.remove(observer);
}
public void notifyAllObserver(String newState){
for (Observer ob : observers) {
ob.update(newState );
}
}
public String getSubjectName() {
return subjectName;
}
public void setSubjectName(String subjectName) {
this.subjectName = subjectName;
}
}
3、ConcreteSubject 具体通知者
package com.mfc.design.观察者模式;
/**
* @author MouFangCai
* @date 2019/10/16 10:44
*
* 具体通知者
*/
public class ConcreteSubject extends Subject {
private String state;
public ConcreteSubject(String name) {
setSubjectName(name);
}
public void change(String newState) {
this.state = state;
notifyAllObserver(newState);
}
}
4、Observer:抽象观察者
package com.mfc.design.观察者模式;
/**
* @author MouFangCai
* @date 2019/10/16 10:33
*
* 抽象观察者
*/
public abstract class Observer {
private String name;
private Subject subject;
abstract void update(String newState);
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Subject getSubject() {
return subject;
}
public void setSubject(Subject subject) {
this.subject = subject;
}
}
5、ConcreteObserver:具体观察者
package com.mfc.design.观察者模式;
/**
* @author MouFangCai
* @date 2019/10/16 10:36
*
* 具体观察者
*/
public class ConcreteObserver1 extends Observer {
public ConcreteObserver1(String name, Subject subject) {
this.setName(name);
this.setSubject(subject);
}
@Override
public void update(String newState) {
System.out.println("观察者:" + this.getName() + "——收到[" + this.getSubject().getSubjectName() + "]通知{"+newState +"},改变状态");
}
}
package com.mfc.design.观察者模式;
/**
* @author MouFangCai
* @date 2019/10/16 10:36
*
* 具体观察者
*/
public class ConcreteObserver2 extends Observer {
public ConcreteObserver2(String name, Subject subject) {
this.setName(name);
this.setSubject(subject);
}
@Override
public void update(String newState) {
System.out.println("观察者:" + this.getName() + "——收到[" + this.getSubject().getSubjectName() + "]通知{"+newState +"},改变状态");
}
}
6、客户端测试
package com.mfc.design.观察者模式;
/**
* @author MouFangCai
* @date 2019/10/16 14:09
*/
public class Client_Observer {
public static void main(String[] args) {
Subject subject = new ConcreteSubject("通知者");
ConcreteObserver1 observer1 = new ConcreteObserver1("观察者1", subject);
ConcreteObserver2 observer2 = new ConcreteObserver2("观察者2", subject);
subject.attach(observer2);
subject.attach(observer1);
subject.notifyAllObserver("消息来了");
}
}
7、结果分析
观察者:观察者2——收到[通知者]通知{消息来了},改变状态
观察者:观察者1——收到[通知者]通知{消息来了},改变状态Process finished with exit code 0
对于“观察者模式”简单理解就是:放风,一个哨兵(Subject)观察情况,发现情况就“按铃”通知,具体通知哪些,哨兵也不知道,只有时刻关注“铃铛”的观察者(ConcreteObserver)才会收到消息,做出相应的改变
网友评论