什么是观察者模式?
观察者模式 (Observer Pattern) 是一种行为型设计模式,它定义了一种一对多的依赖关系,当一个对象的状态发生改变时,它的所有依赖者 (观察者) 都会收到通知并自动更新。 在观察者模式中,有两个核心角色:Subject(主题) 和 Observer(观察者)。Subject 对象维护一组观察者,并负责通知它们状态变化的情况。Observer 对象订阅 Subject 对象的状态,并在 Subject 发生状态变化时被通知,并更新自身的状态。
观察者模式的作用
观察者模式的关键是解耦,使得 Subject 和 Observer 之间不直接相互依赖,而是通过抽象接口进行交互。这样,当 Subject 对象的状态发生变化时,Observer 对象不需要知道具体的变化细节,只需要接收通知并做出相应的响应即可。
观察者模式的案例
public class Child{
Boolean cry;
public Child(Boolean cry) {
this.cry = cry;
}
public void wakeUp(){
cry =true;
System.out.println("child 哭醒了");
Dad dad = new Dad();
dad.wake();
}
}
package com.mult.strategy.observer;
public class Dad {
public void wake() {
System.out.println("dad 起床哄孩子");
}
}
public class Observer1 {
public static void main(String[] args) {
Child child = new Child(false);
child.wakeUp();
}
}
上面案列中child属于被观察对象,dad属于观察者,当child触发wakeup()方法之后,就会调起观察者的wakeUp()方法。这种就是属于简单的观察者模式的实现,但是有一些问题。 首先每个观察者都需要在被观察对象里面创建,这就导致扩展观察者的时候,变得很繁琐。我们可以通过下面的方案做实现。
package com.mult.strategy.observer;
/**
* @author mult
*/
public class Mom implements Observer{
@Override
public void wakeUp() {
System.out.println("mom醒来 喂吃的");
}
}
package com.mult.strategy.observer;
import java.util.ArrayList;
import java.util.List;
public class Child2 {
Boolean cry;
List<Observer> observers = new ArrayList<>();
public Child2(Boolean cry) {
this.cry = cry;
}
public void wakeUp(){
cry =true;
for (Observer observer : observers) {
observer.wakeUp();
}
}
}
package com.mult.strategy.observer;
public class Observer2 {
public static void main(String[] args) {
Child2 child = new Child2(false);
List<Observer> observers = new ArrayList<>();
observers.add(new Mom());
child.observers = observers;
child.wakeUp();
}
}
这个形式目前解决了观察者对象扩展的问题,只需要在集合中添加观察对象就可以完成扩展。 但是还有一个数据传递的问题需要解决。观察者有的时候是需要被观察对象的某些数据,这个时候我们就要传递数据了。
package com.mult.strategy.observer;
import java.time.LocalDateTime;
public class CryMsg<T> {
T t;
Boolean cry;
public CryMsg(T t,Boolean cry, LocalDateTime cryTime) {
this.t = t;
this.cry = cry;
this.cryTime = cryTime;
}
LocalDateTime cryTime;
}
public interface ObserverMsg {
void wakeUp(CryMsg cryMsg);
}
package com.mult.strategy.observer;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
public class Child3 {
Boolean cry;
List<ObserverMsg> observers = new ArrayList<>();
public Child3(Boolean cry) {
this.cry = cry;
}
public void wakeUp(){
cry =true;
for (ObserverMsg observer : observers) {
observer.wakeUp(new CryMsg<Child3>(this,this.cry, LocalDateTime.now()));
}
}
}
package com.mult.strategy.observer;
import java.util.ArrayList;
import java.util.List;
public class Observer3 {
public static void main(String[] args) {
Child3 child = new Child3(false);
List<ObserverMsg> observers = new ArrayList<>();
observers.add(new GrandMom());
child.observers = observers;
child.wakeUp();
}
}
现在的方案就是我们所见到的最终的观察者模式的形态了。