今天接触公司项目代码,发现使用了观察者设计模式,在这里做一下总结。
使用观察者模式,有如下好处:
- 可以使代码结构更加清晰有调理,
- 处理逻辑类变成可插拔的,耦合性较低
- 代码变得更通用
1. 关键概念
- 观察者
实现业务逻辑 - 被观察者(观察者的容器)
(1) 注册观察者
(2) 删除观察者
(3) 通知观察者(遍历观察者并调用他的业务逻辑方法)
2. 实现
- 实现被观察者的接口
/**
* 实现观察者模式
* 观察器控制接口(被观察者)
* 负责实现注册观察者、删除观察者、通知观察者
* Created by feiwen on 2018/4/20.
*/
public interface EventListenerManger {
/**
* 注册观察者
* @param e
*/
void registerListener(MyEventEnum myEventEnum,MyEventListener e);
/**
* 删除观察者
* @param e
*/
void removeListener(MyEventEnum myEventEnum,MyEventListener e);
/**
* 通知所有的观察者
*/
void fireEvent(MyEventEnum myEventEnum);
- 实现被观察者的实现类
import org.springframework.stereotype.Component;
import java.util.EnumMap;
import java.util.Map;
import java.util.Vector;
/**
* Created by feiwen on 2018/4/20.
*/
@Component
public class EventListenerMangerImpl implements EventListenerManger {
//这里集合使用map集合可以将观察者进行分类,不同类别,同时拥有几个观察者
private static Map<MyEventEnum, Vector<MyEventListener>> eventListeners=new EnumMap<MyEventEnum, Vector<MyEventListener>>(MyEventEnum.class);
@Override
public void registerListener(MyEventEnum myEventEnum,MyEventListener e) {
Vector<MyEventListener> listeners=eventListeners.get(myEventEnum);
if(listeners==null){
listeners=new Vector<>();
}else{
for (MyEventListener listener:listeners){
if(listener.getClass()==e.getClass()){
return;
}
}
}
listeners.add(e);
eventListeners.put(myEventEnum,listeners);
}
@Override
public void removeListener(MyEventEnum myEventEnum,MyEventListener e) {
Vector<MyEventListener> listeners=eventListeners.get(myEventEnum);
if(listeners!=null){
listeners.remove(e);
}
}
@Override
public void fireEvent(MyEventEnum myEventEnum) {
Vector<MyEventListener> listeners=eventListeners.get(myEventEnum);
if(listeners!=null){
for(MyEventListener listener:listeners){
listener.fire();
}
}
}
}
- 实现观察者接口
/**
* Created by feiwen on 2018/4/20.
*/
public interface MyEventListener {
/**
* 触发事件实现业务逻辑
*/
void fire();
}
- 实现观察者的实现类
/**
* 实现观察者模式
* 观察者接口
* 负责实现业务逻辑
* Created by feiwen on 2018/4/20.
*/
public class CallBackEventListener implements MyEventListener{
@Override
public void fire() {
System.out.println("触发callback的业务逻辑");
}
}
- 枚举类
/**
* 事件枚举类
* Created by feiwen on 2018/4/20.
*/
public enum MyEventEnum {
CALLBACK_EVENT;
}
- 调用方
@RequestMapping("/testListener")
public void testListener(){
logger.info("进入监听器的测试方法");
eventListenerManger.registerListener(MyEventEnum.CALLBACK_EVENT,new CallBackEventListener());
eventListenerManger.fireEvent(MyEventEnum.CALLBACK_EVENT);
}
优化
在观察者代码中可以在构造方法中将自己注册到被观察中,这样就不用在调用发使用注册方法。
网友评论