说明
观察者模式主要用于多个观察者(Observer)需要关注到同一目标对象的状态变化,根据状态变化做出响应的情况。比如父母关注孩子的场景。
使用
1、定义被观察者抽象类,申明通知观察者方法
2、具体被观察者继承观察者抽象类,实现通知观察者方法
3、定义观察者接口,申明响应方法
实现
/**
* 抽象被观察对象
* 具备添加和删除观察者的方法
*/
public abstract class Subject {
List<Observer> observerList;
public void addObserver(Observer observer){
observerList.add(observer);
}
public void deleteObserver(Observer observer){
observerList.remove(observer);
}
/**
* 提醒被观察者方法
*/
public abstract void notifyObservers();
}
/**
* 孩子是具体被观察者,继承抽象被观察者
*/
public class Son extends Subject {
public Son() {
this.observerList = new ArrayList<>();
}
@Override
public void notifyObservers() {
for (Observer observer : observerList) {
observer.response();
}
}
}
/**
* 观察者接口
*/
public interface Observer {
void response();
}
/**
* 妈妈是具体观察者
*/
public class Mother implements Observer{
@Override
public void response() {
System.out.println("Mother response");
}
}
/**
* 爸爸是具体观察者
*/
public class Father implements Observer{
@Override
public void response() {
System.out.println("father response...");
}
}
//测试
public class ObserverTest {
public static void main(String[] args) {
Subject son = new Son();
//添加观察者
Observer one = new Father();
son.addObserver(one);
Observer two = new Mother();
son.addObserver(two);
son.notifyObservers();
}
}
测试结果
以上是最简单的观察者模式的使用,实际上在使用过程种父母可能需要根据孩子的情况做出不同的响应,因此,需要将被观察者产生的情况封装成一个事件对象,观察者根据被观察者产生的具体事件做出不同的响应。
代码演示
还是上文提到的场景
/**
* 抽象被观察对象
* 具备添加和删除观察者的方法
*/
public abstract class Subject {
List<Observer> observerList ;
public void addObserver(Observer observer){
observerList.add(observer);
}
public void deleteObserver(Observer observer){
observerList.remove(observer);
}
/**
* 提醒被观察者方法
*/
public abstract void notifyObservers(SubjectEvent subjectEvent);
}
/**
* 孩子是具体被观察者,继承抽象被观察者
*/
public class Son extends Subject {
public Son() {
this.observerList = new ArrayList<>();
}
@Override
public void notifyObservers(SubjectEvent subjectEvent) {
for (Observer observer : observerList) {
observer.response(subjectEvent);
}
}
}
/**
* 观察者接口
*/
public interface Observer {
void response(SubjectEvent subjectEvent);
}
/**
* 妈妈是具体观察者
*/
public class Mother implements Observer{
@Override
public void response(SubjectEvent subjectEvent) {
System.out.println("Mother response fro "+subjectEvent.getSource()+" "+subjectEvent.getMsg());
}
}
/**
* 爸爸是具体观察者
*/
public class Father implements Observer{
@Override
public void response(SubjectEvent subjectEvent) {
System.out.println("father response for "+subjectEvent.getSource()+" "+subjectEvent.getMsg());
}
}
/**
* 事件对象需要记录事件源,比如是哪个孩子
*/
public class SubjectEvent {
private String msg;
private Subject source;
public SubjectEvent(String msg, Subject source) {
this.msg = msg;
this.source = source;
}
public SubjectEvent() {
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Subject getSource() {
return source;
}
public void setSource(Subject source) {
this.source = source;
}
}
/**
* 测试
*/
public class ObserverTest {
public static void main(String[] args) {
Subject son = new Son();
//添加观察者
Observer one = new Father();
son.addObserver(one);
Observer two = new Mother();
son.addObserver(two);
//定义事件
SubjectEvent event = new SubjectEvent("baby cry!",son);
son.notifyObservers(event);
}
}
测试结果
总结
通过观察者实现观察者接口,被观察者持有观察者接口引用,降低了被观察者和具体观察者之间的耦合。加入事件对象,让观察者的响应更加丰富