一、 业务场景
业务在初始迭代中开发了游戏防沉迷系统,用户在玩游戏时SDK每隔一分钟上报心跳,记录用户的游戏时长、登陆、上下线行为等
随着业务的发展,新增了如下功能:
a、用户玩游戏自动关注游戏酱
b、数据埋点
c、用户玩游戏累计积分
d、用户上下线、登陆行为上报中宣部
e、用户玩游戏期间生成SESSION信息供其他业务场景使用
这些功能均依赖于用户的玩游戏这一时机,将来可能还会有更多的功能添加进来,为了避免将如上功能与防沉迷心跳耦合起来,保持开闭原则,通过责任链的设计模式完成如上开发;
二、代码示例
(1)定义接口
public interface AddictionTaskHandler {
boolean matchTask(int taskType);
boolean handleTask(long userId, String appId, Map<String,String> otherParams);
}
(2)实现接口的链式任务类
//任务1 : 玩游戏自动关注游戏酱官方账号
public class FellowTask implements AddictionTaskHandler {
@Override
public boolean matchTask(int taskType) {
return taskType == AddictionTaskType.FELLOW
}
@Override
public boolean handleTask(long userId, String appId , Map<String,String> otherParams) {
//TODO
}
}
//任务2 : 玩游戏赠送积分任务
public class CurrencyTask implements AddictionTaskHandler {
@Override
public boolean matchTask(int taskType) {
return taskType == AddictionTaskType.CURRENCY;
}
@Override
public boolean handleTask(long userId, String appId, Map<String,String> otherParams) {
//TODO
}
}
//其他任务省略...
(3) Handler 服务启动时注册实现AddictionTaskHandler接口的
public class HandlerLoader implements ApplicationContextAware {
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
TaskDispatcher dispatcher = applicationContext.getBean(TaskDispatcher.class);
Map<String, AddictionTaskHandler> handlerBeans = applicationContext.getBeansOfType(AddictionTaskHandler.class);
if(null != handlerBeans && handlerBeans.size()>0){
handlerBeans.forEach(dispatcher::register);
}
}
}
(4)链式任务派发执行
public class TaskDispatcher {
//String为对应注册的bean名字
private Map<String, AddictionTaskHandler> handlers = new HashMap<>();
public void register(String beanName, AddictionTaskHandler taskHandler){
if(!handlers.containsKey(beanName)){
handlers.put(beanName, taskHandler);
}
}
public void chainTask(long userId, String appId,Map<String,String> otherParams){
for (Map.Entry<String, AddictionTaskHandler> entry : handlers.entrySet()){
AddictionTaskHandler addictionTaskHandler = entry.getValue();
addictionTaskHandler.handleTask(userId,appId,otherParams);
}
}
}