天天看点

JAVA责任链设计模式在项目中的体现

项目需求

项目包含如下业务逻辑

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;
           

之后在方法里直接使用

后台依次触发下发、安装、启动、更新配置的流程

继续阅读