intro
我们在看源码的时候竟会看到类似于addListener
,publishEvent
,fireEvent
这样的代码,这都是观察者模式。
观察者模式的模型很简单,就是观察者观察被观察者,当被观察者有事件发生的时候,观察者作出反应。
举个例子:
妈妈、爸爸或者其他人是观察者,他们观察着被观察者,当被观察者(小孩)哭了或者是饿了,他们要分别作出应有的反应。
code
在这里我们还要抽象出事件这个对象,事件中,要包含事件源,即触发事件的对象是谁。
事件也是可以有链条式的继承关系的。我们在此演示两个事件:饿了和哭了。我想说明的是,事件有不同的实现。
我们代码实现一下:
首先是观察者:
public interface Observer {
void actionOEvent(Event event);
}
观察者要根据事件作出反应。
观察者有爸:
public class Dad implements Observer {
@Override
public void actionOEvent(Event event) {
if(WakeUpEvent.class.equals(event.getClass())){
System.out.println("dad has observed child crying...");
}
if(HungryEvent.class.equals(event.getClass())){
System.out.println("dad has observer child being hungry...");
}
}
}
爸看到如果是醒来事件,就怎么样怎么样,如果是饿了事件,就怎么样怎么样。
观察者还有妈:
public class Mum implements Observer {
@Override
public void actionOEvent(Event event) {
if(WakeUpEvent.class.equals(event.getClass())){
System.out.println("mum has observed child crying...");
}
if(HungryEvent.class.equals(event.getClass())){
System.out.println("mum has observed child being hungry...");
}
}
}
妈也一样。
然后我们讲事件对象:
public abstract class Event<T> {
abstract T getSource();
}
某个事件必须包含事件源(就是触发者是谁)。
具体的醒来事件:
public class WakeUpEvent extends Event<Child> {
private long time;
private String location;
private Child source;
public WakeUpEvent(long time, String location, Child source) {
this.time = time;
this.location = location;
this.source = source;
}
@Override
Child getSource() {
return source;
}
}
它的事件源就是Child
,然后醒来的话我们要知道啥时醒来的,在哪里醒来的。
public class HungryEvent extends Event<Child> {
private long when;
private Child source;
public HungryEvent(long when, Child source) {
this.when = when;
this.source = source;
}
@Override
Child getSource() {
return source;
}
}
饿了事件的事件源也是Child
,然后我们要知道啥时候饿了。
被观察者:
public class Child {
private boolean cry = false;
private boolean isHungry = false;
private List<Observer> observerList = new ArrayList<>();
{
observerList.add(new Dad());
observerList.add(new Mum());
}
public void wakeUp(){
cry = true;
WakeUpEvent event = new WakeUpEvent(System.currentTimeMillis(),"bed",this);
for(Observer observer : observerList){
observer.actionOEvent(event);
}
}
public void getHungry(){
isHungry = true;
HungryEvent event = new HungryEvent(System.currentTimeMillis(),this);
for (Observer observer : observerList) {
observer.actionOEvent(event);
}
}
}
小孩有哭和饿两个属性。
然后小孩有两个观察者:爸爸和妈妈。
小孩醒来,就会触发醒来事件,然后父母分别作出反应。
小孩饿了,就会触发饿了事件,然后父母分别作出反应。
可以看到,代码的解耦程度很高。
test
public class Test {
public static void main(String[] args) {
Child child = new Child();
child.getHungry();
}
}
public class Test {
public static void main(String[] args) {
Child child = new Child();
child.wakeUp();
}
}