观察者模式推导解析

Observer pattern

intro

我们在看源码的时候竟会看到类似于addListenerpublishEventfireEvent这样的代码,这都是观察者模式。

观察者模式的模型很简单,就是观察者观察被观察者,当被观察者有事件发生的时候,观察者作出反应。

举个例子:

妈妈、爸爸或者其他人是观察者,他们观察着被观察者,当被观察者(小孩)哭了或者是饿了,他们要分别作出应有的反应。


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();
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值