java实现观察者模式
发布日期:2021-06-28 19:59:38 浏览次数:2 分类:技术文章

本文共 3672 字,大约阅读时间需要 12 分钟。

为了看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"
,
"跳转百度"
,
"
")
;
        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":" "}
ClickListener onEventAttach, event={"code":1,"source":{"id":"a_baidu","name":"跳转百度","value":" "}}
AllEventListener onEventAttach,event={"code":1,"source":{"id":"a_baidu","name":"跳转百度","value":" "}}
EventSource destory!
AllEventListener onEventAttach,event={"code":-1}

转载地址:https://blog.csdn.net/xxxxssss12/article/details/79311425 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:ServerSocketChannel+Selector实现多路复用io
下一篇:enum是什么

发表评论

最新留言

不错!
[***.144.177.141]2024年04月15日 23时54分59秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章