java实现观察者模式

为了看netty源码做准备。


观察者模式、发布-订阅模型、reactor模式本质上类似,通过事件回调来解耦动作执行者和观察者。
观察者模式中主要分三个角色:
  1. 观察者(监听器)
  2. 事件(执行的动作)
  3. 事件源(监视对象)

具体的实现方式分两步:
  1. 观察者初始化,绑定到事件源
  2. 事件发生时通知绑定了该事件的观察者

代码如下:
  1. 观察者:
public interface Listener {
    void onEventAttach(Event event) ;
}
两个实现:AllEventListener和ClickListener
public class AllEventListener implements Listener {
    @Override
    public void onEventAttach(Event event) {
        System. out.println( "AllEventListener onEventAttach,event=" + JSON. toJSONString(event)) ;
    }
}

public class ClickListener implements Listener {
    @Override
    public void onEventAttach(Event event) {
        System. out.println( "ClickListener onEventAttach, event=" + JSON. toJSONString(event)) ;
    }
}
  1. 事件对象
public class Event {
    public static final int INIT = 0 ;
    public static final int CLICK = 1 ;
    public static final int DESTORY = - 1 ;

    private int code ;
    private Object data ;

    public Event( int code , Object data) {
        this. code = code ;
        this. data = data ;
    }

    public int getCode() { return code ;}

    public Object getData() { return data ;}
}
  1. 事件源
import com.alibaba.fastjson.JSON ;
import java.util.* ;
public class EventSource {
    public final Object BIND_LOCK = new Object() ;
    public Map<Integer , Set<Listener>> eventListenerMap = new HashMap<>() ;

    public void bind(Listener listener , int eventCode) {
        synchronized ( BIND_LOCK) {//这个lock可以优化
            Set<Listener> listenerSet = eventListenerMap.get(eventCode) ;
            if (listenerSet == null || listenerSet.isEmpty()) {
                listenerSet = new HashSet<>() ;
            }
            listenerSet.add(listener) ;
            eventListenerMap.put(eventCode , listenerSet) ;
        }
    }

    public void bind(Listener listener , List<Integer> eventCodeList) {
        eventCodeList.forEach(eventCode -> bind( listener , eventCode)) ;
    }

    public EventSource() {
        System. out.println( "EventSource create!") ;
    }

    public void init() {
        System. out.println( "EventSource init!") ;
        notifyListener(Event. INIT , null) ;
    }

    public void click(Element element) {// element自己新建一个bean,或者改成Map/Object即可
        System. out.println( "EventSource click!element=" + JSON. toJSONString(element)) ;
        notifyListener(Event. CLICK , element) ;
    }

    public void destory() {
        System. out.println( "EventSource destory!") ;
        notifyListener(Event. DESTORY , null) ;
    }
    private void notifyListener( int eventCode , Object data) {
        Set<Listener> listenerSet = eventListenerMap.get(eventCode) ;
        if (listenerSet != null && !listenerSet.isEmpty()) {
            Event event = new Event(eventCode , data) ;
            listenerSet.forEach(listener -> listener.onEventAttach( event)) ;
        }
    }
}
  1. 演示代码
public class Demo {
    public static void main(String[] args) {
        EventSource source = new EventSource() ;
        Element element1 = new Element( "btn_query" , "查询" , "查询1") ;
        Element element2 = new Element( "a_baidu" , "跳转百度" , " www.baidu.com ") ;
        Listener all = new AllEventListener() ;
        Listener clickListener = new ClickListener() ;
        source.bind(clickListener , Event. CLICK) ;
        source.bind(all , Arrays. asList(Event. INIT , Event. CLICK , Event. DESTORY)) ;
        source.init() ;
        source.click(element1) ;
        source.click(element2) ;
        source.destory() ;
    }
}
输出如下:
EventSource create!
EventSource init!
AllEventListener onEventAttach,event={"code":0}
EventSource click!element={"id":"btn_query","name":"查询","value":"查询1"}
ClickListener onEventAttach, event={"code":1,"source":{"id":"btn_query","name":"查询","value":"查询1"}}
AllEventListener onEventAttach,event={"code":1,"source":{"id":"btn_query","name":"查询","value":"查询1"}}
EventSource click!element={"id":"a_baidu","name":"跳转百度","value":" www.baidu.com"}
ClickListener onEventAttach, event={"code":1,"source":{"id":"a_baidu","name":"跳转百度","value":" www.baidu.com"}}
AllEventListener onEventAttach,event={"code":1,"source":{"id":"a_baidu","name":"跳转百度","value":" www.baidu.com"}}
EventSource destory!
AllEventListener onEventAttach,event={"code":-1}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
观察者模式是一种常见的设计模式,它的主要思想是在对象之间建立一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。 在Java中,观察者模式实现需要定义两个角色:Subject(主题)和Observer(观察者)。Subject负责维护一组观察者对象,以及通知它们状态的变化;而Observer则负责接收Subject的通知,并做出相应的处理。 下面是一个简单的Java实现: ```java import java.util.ArrayList; import java.util.List; // 主题接口 interface Subject { void attach(Observer observer); // 添加观察者 void detach(Observer observer); // 移除观察者 void notifyObservers(); // 通知所有观察者 } // 观察者接口 interface Observer { void update(); // 更新状态 } // 具体主题类 class ConcreteSubject implements Subject { private List<Observer> observers = new ArrayList<>(); public void attach(Observer observer) { observers.add(observer); } public void detach(Observer observer) { observers.remove(observer); } public void notifyObservers() { for (Observer observer : observers) { observer.update(); } } // 主题状态的变化 public void changeState() { // do something notifyObservers(); // 通知所有观察者 } } // 具体观察者类 class ConcreteObserver implements Observer { private String name; public ConcreteObserver(String name) { this.name = name; } public void update() { System.out.println(name + " has received the update."); } } // 测试 public class ObserverPatternDemo { public static void main(String[] args) { Subject subject = new ConcreteSubject(); Observer observer1 = new ConcreteObserver("Observer1"); Observer observer2 = new ConcreteObserver("Observer2"); Observer observer3 = new ConcreteObserver("Observer3"); subject.attach(observer1); subject.attach(observer2); subject.attach(observer3); ((ConcreteSubject) subject).changeState(); subject.detach(observer2); ((ConcreteSubject) subject).changeState(); } } ``` 在这个例子中,我们定义了Subject和Observer两个接口,以及它们的具体实现类ConcreteSubject和ConcreteObserver。其中ConcreteSubject负责维护一组观察者对象,并在状态变化时通知它们;而ConcreteObserver则负责接收Subject的通知,并做出相应的处理。 在测试代码中,我们创建了一个ConcreteSubject对象,并向它添加了三个ConcreteObserver观察者。然后我们调用changeState()方法改变主题的状态,这会触发ConcreteSubject通知所有观察者。最后我们移除了一个观察者,并再次调用changeState()方法,这时只有两个观察者会收到通知。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值