观察者模式,也叫发布-订阅模式,定义了一种一对多的关系,多个观察者可以同时监听某一个主题,这个主题的对象的状态发生变化时,会通知所有的观察者对象
类图
工程目录
代码
AbstractSubject.java
package com.company.pattern.demo10;
import java.util.ArrayList;
import java.util.List;
/**
* 主题、抽象通知者
* @author blazar
*/
public abstract class AbstractSubject {
private List<MyObserver> myObservers = new ArrayList<>();
/**
* 增加观察者
* @param myObserver
*/
public void attach(MyObserver myObserver){
myObservers.add(myObserver);
}
/**
* 移除观察者
* @param myObserver
*/
public void detach(MyObserver myObserver){
myObservers.remove(myObserver);
}
public void myNotify(){
for(MyObserver myObserver : myObservers){
myObserver.update();
}
}
}
MyObserver.java
package com.company.pattern.demo10;
/**
* 观察者接口
* @author blazar
*/
public interface MyObserver {
/**
* 更新方法
*/
void update();
}
ConcreteSubject.java
package com.company.pattern.demo10;
/**
* 具体主题、具体通知者
* @author blazar
*/
public class ConcreteSubject extends AbstractSubject{
/**
* 具体被观察者状态
*/
private String subjectState;
public String getSubjectState() {
return subjectState;
}
public void setSubjectState(String subjectState) {
this.subjectState = subjectState;
}
}
ConcreteObserver.java
package com.company.pattern.demo10;
/**
* 具体观察者
* @author blazar
*/
public class ConcreteObserver implements MyObserver {
private String name;
private String observerState;
private ConcreteSubject subject;
public ConcreteObserver(String name, ConcreteSubject subject) {
this.name = name;
this.subject = subject;
}
@Override
public void update() {
observerState = subject.getSubjectState();
System.out.println(String.format("观察者%s的新状态是%s", name, observerState));
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getObserverState() {
return observerState;
}
public void setObserverState(String observerState) {
this.observerState = observerState;
}
public ConcreteSubject getSubject() {
return subject;
}
public void setSubject(ConcreteSubject subject) {
this.subject = subject;
}
}
测试类 Main.java
package com.company.pattern.demo10;
/**
* 测试类
* @author blazar
*/
public class Main {
public static void main(String[] args) {
ConcreteSubject concreteSubject = new ConcreteSubject();
concreteSubject.attach(new ConcreteObserver("X", concreteSubject));
concreteSubject.attach(new ConcreteObserver("Y", concreteSubject));
concreteSubject.setSubjectState("ABC");
concreteSubject.myNotify();
}
}
使用场景
- 观察者模式是为了维护不同类的相关对象的一致性而产生的;我们不希望为维持一致性而使各类紧密耦合,这样会给维护、扩展和重用带来麻烦;
- 观察者模式让耦合的双方都依赖于抽象,而不是依赖于具体,从而使得各自的变化不会直接影响到另一边;
缺陷
上边说过,观察者模式是将原来对象之间的直接耦合改成了对象所实现的接口之间的耦合;接口之间依然是需要耦合的;但是如果一些类没有实现抽象观察者的接口,就没法被通知到了啊。
改进方法
不同的语言引入了不同的机制解决这个问题,如:C#中的委托机制,这里涉及到语言细节,暂不做描述。
参考《大话设计模式》