定义:当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知它的依赖对象。
个人理解:这个模式应用最多的应该就是监听器了(各种event,listener),我接下来代码举例,用婴儿哭,然后需要喂等举例。
UML图解:
优点:观察者和被观察者是抽象耦合。
缺点:注意循环依赖,如果循环调用,可能系统会炸掉。
代码:
/**
* 有很多时候,观察者需要根据事件的具体情况来进行处理
* 大多数时候,我们处理事件的时候,需要事件源对象
* 事件也可以形成继承体系
*/
class Child {
private boolean cry = false;
private List<Observer> observers = new ArrayList<>();
{
observers.add(new Dad());
observers.add(new Mum());
observers.add(new Dog());
//lamda表达式可替代
observers.add((e)->{
System.out.println("ppp");
});
//hook callback function
}
//定义哭的方法
public boolean isCry() {
return cry;
}
//根据是否哭,然后区调用观察者们对应的动作
public void wakeUp() {
cry = true;
wakeUpEvent event = new wakeUpEvent(System.currentTimeMillis(), "bed", this);
for(Observer o : observers) {
o.actionOnWakeUp(event);
}
}
}
//抽象方法事件源
abstract class Event<T> {
abstract T getSource();
}
//针对哪个对象的事件
class wakeUpEvent extends Event<Child>{
long timestamp;
String loc;
Child source;
public wakeUpEvent(long timestamp, String loc, Child source) {
this.timestamp = timestamp;
this.loc = loc;
this.source = source;
}
@Override
Child getSource() {
return source;
}
}
//观察者接口
interface Observer {
void actionOnWakeUp(wakeUpEvent event);
}
//具体哪些观察者,并做了哪些事
class Dad implements Observer {
public void feed() {
System.out.println("dad feeding...");
}
@Override
public void actionOnWakeUp(wakeUpEvent event) {
feed();
}
}
class Mum implements Observer {
public void hug() {
System.out.println("mum hugging...");
}
@Override
public void actionOnWakeUp(wakeUpEvent event) {
hug();
}
}
class Dog implements Observer {
public void wang() {
System.out.println("dog wang...");
}
@Override
public void actionOnWakeUp(wakeUpEvent event) {
wang();
}
}
public class Main {
public static void main(String[] args) {
Child c = new Child();
//do sth
c.wakeUp();
}
}
总结:根据UML图可以看出,这种模式需要事件源本身,监听者(具体实现什么动作)以及事件(发生了什么),这个模式还是去看一下监听器的源码较好。观察者模式多于责任链模式结合使用。