项目需求
项目包含如下业务逻辑
1.前端界面点击“新增采集”按钮,进入后台逻辑。
2.后台开始部署FileBeat实例的逻辑。部署过程包含下发、安装、启动、更新配置等操作,每个操作都是一次http接口调用。只有当前一个操作完成后,才能进行下一个操作,否则操作中断。
传统设计
由于“只有当前一个操作完成后,才能进行下一个操作,否则操作中断”,所以我们定义一个接口方法,方法使用如下伪代码结构:每个操作都用try-catch包裹
public void deploy(FileBeatInstanceDTO fileBeatInstanceDTO, FileBeatInstance fileBeatInstance){
try{
//下发操作
......
......
}catch(e){
throw e
}
try{
//安装操作
......
......
}catch(e){
throw e
}
try{
//启动操作
......
......
}catch(e){
throw e
}
try{
//更新配置操作
......
......
}catch(e){
throw e
}
}
可以发现,当涉及多个操作时,一个方法里的代码量巨大。假如后期加入更多操作,代码维护起来也不容易。
责任链模式的设计
1.思路分析
分析“只有当前一个操作完成后,才能进行下一个操作,否则操作中断”的特点,我们可以将其比喻为一个链条:链条上存在多个操作点,请求在链条上从前往后传递,前一个操作点成功后,将请求交给下一个操作点————这比较符合责任链模式。
所以,我们可以参考责任链的设计思路,将上述代码进行改造。下面我直接上代码。
2.代码
1.抽象父类FileBeatInstanceDeployOperator
包含
FileBeatInstanceDeployOperator
类型的
successor
成员,以及处理请求的抽象
operateByAddCollect
方法,由子类实现。
public abstract class FileBeatInstanceDeployOperator {
private FileBeatInstanceDeployOperator successor;
public void setSuccessor(FileBeatInstanceDeployOperator successor){
this.successor = successor;
}
public FileBeatInstanceDeployOperator getSuccessor() {
return successor;
}
public abstract void operateByAddCollect(FileBeatInstanceDTO fileBeatInstanceDTO, FileBeatInstance fileBeatInstance);
}
2.下发类IssueOperator
FileBeatInstanceDeployOperator
的子类,通过
@PostConstruct
在项目启动时设置下一个请求处理者
InstallOperator
@Component
@Slf4j
public class IssueOperator extends FileBeatInstanceDeployOperator{
@Autowired
private InstallOperator installOperator;
@Override
public void operateByAddCollect(FileBeatInstanceDTO fileBeatInstanceDTO, FileBeatInstance fileBeatInstance) {
try {
//下发业务逻辑
......
......
}catch (Exception e){
throw e
}
//如果下一个处理者不为空,将请求交给下一个处理者
if(getSuccessor() != null){
getSuccessor().operateByAddCollect(fileBeatInstanceDTO, fileBeatInstance);
}
}
@PostConstruct
public void setSuccessor(){
setSuccessor(installOperator);
}
}
3.安装类InstallOperator
FileBeatInstanceDeployOperator
的子类,通过
@PostConstruct
在项目启动时设置下一个请求处理者
StartOperator
@Component
@Slf4j
public class InstallOperator extends FileBeatInstanceDeployOperator{
@Autowired
private StartOperator startOperator;
@Override
public void operateByAddCollect(FileBeatInstanceDTO fileBeatInstanceDTO, FileBeatInstance fileBeatInstance) {
try {
//安装业务逻辑
......
......
}catch (Exception e){
throw e
}
if(getSuccessor() != null){
getSuccessor().operateByAddCollect(fileBeatInstanceDTO, fileBeatInstance);
}
}
@PostConstruct
public void setSuccessor(){
setSuccessor(startOperator);
}
}
4.启动类InstallOperator
启动类
InstallOperator
以及后面更新配置类
UpdateOperator
的设计,都与上面类似,此处就不再展示多余代码。
3.使用
在controller中,注入
IssueOperator
@Autowired
private IssueOperator issueOperator;
之后在方法里直接使用
后台依次触发下发、安装、启动、更新配置的流程