一:定义通知者(notice) 和 观察者(observer) 两个接口
PullCustDataNotice.java:
//拉取数据通知者接口
public interface PullCustDataNotice {
void removeObserver(PullCustDataObserver observer);
void addObserver(PullCustDataObserver observer);
void notice(Map<String,Object> map);
}
PullCustDataObserver.java:
//拉取数据观察者接口
public interface PullCustDataObserver {
void update(Map<String, Object> map);
}
二:写通知者和观察者的具体实现
通知者具体实现
DataNotice.java:
/**
* @description 拉取数据通知者实现
* @author sgl
* @date 2019/12/9 下午 14:11
* @params
* @return
*/
public class DataNotice implements PullCustDataNotice {
//用来存放要通知的观察者列表
List<PullCustDataObserver> list = new ArrayList<>(5);
@Override
public void removeObserver(PullCustDataObserver observer) {
list.remove(observer);
}
@Override
public void addObserver(PullCustDataObserver observer) {
list.add(observer);
}
//按照加入顺序逐个通知观察者执行逻辑
@Override
public void notice(Map<String,Object> map){
if (!CollectionUtils.isEmpty(list)) {
list.forEach(m -> {
m.update(map);
});
}
}
}
观察者具体实现
PullConsumeData.java:
/**
* @description 拉取消耗数据
* @author sgl
* @date 2019/12/17 下午 13:37
*/
@Slf4j
@Component
public class PullConsumeData implements PullCustDataObserver {
//map可以用来传递各个观察者需要用到的公共参数,比如拉取数据的开始结束时间
@Override
public void update(Map<String, Object> map) {
//具体拉取消耗数据逻辑实现
}
}
PullCustFollowData.java:
/**
* @description 拉取跟进数据
* @author sgl
* @date 2019/12/11 下午 13:37
*/
@Slf4j
@Component
public class PullCustFollowData implements PullCustDataObserver {
@Override
public void update(Map<String, Object> map) {
//处理拉取跟进数据的具体逻辑实现
}
}
三:测试启动组合观察者
/**
* @description (定时任务)拉取客户各项数据
* @author sgl
* @date 2019/12/11 下午 14:30
*/
@Override
public void pullCustomerExpendData() {
Date now = new Date();
String nowStr = DateUtils.dateToStr(now);
log.info("开始拉取客户各项拓展数据 操作日期: -> {}",nowStr);
Map<String,Object> map = new HashMap<>(1);
map.put("date",now);
//先生成一个通知者
DataNotice dataNotice = new DataNotice();
//把参与的拉取数据的观察者加入进去
dataNotice.addObserver(pullConsumeData);
dataNotice.addObserver(custFollowData);
//执行通知方法
dataNotice.notice(map);
}
上面例子只使用到了一个通知者,当然可以根据需求的不同去实现不同的通知者,然后组装不同的观察者,可拓展性比较强。
注意:
1:上面的观察者推荐使用注入的方式再添加进通知者中
@Resource private PullCustFollowData custFollowData; @Resource private PullConsumeData pullConsumeData;
dataNotice.addObserver(pullConsumeData);
dataNotice.addObserver(custFollowData);
因为如果是new的话,那么观察者对象中是无法使用注入的属性的,都为NULL,应为spring环境中,new的对象是无法注入的!
2:每个观察者的具体实现中最好做好try catch 处理,应为通知者里面数循环调用观察者的,如果一个报错就会影响后面还没有执行的观察者的逻辑无法执行!