背景:
当前CI构建调度层这边,状态追踪与回写是比较重要的一环。当前大致状态有distribute / building / error / missing / abort / exception / completed等,配合Quartz框架进行状态捕获。之前的代码写的比较乱, 状态间符合转化执行的关系,因此考虑状态模式来进行重构。此处写个示例代码及使用。
关于状态模式的使用场景及概念介绍,此处不进行阐述,可参阅其余博客。
代码示例:
1.抽象状态类
public abstract class AbstractState {
// 总状态接口
// 上下文对象
protected ActivityContext activityContext;
public void setActivityContext(ActivityContext context) {
this.activityContext = context;
}
// type标识状态类型
public abstract String getState();
// 所有状态及对应操作
public abstract boolean state1(Activity activity);
public abstract boolean state2(Activity activity);
public abstract boolean state3(Activity activity);
}
2.以三个不同的状态为例
// state1
@Component
@Slf4j
public class State1 extends AbstractState {
public static final String STATE = "state1";
// 假设下一个状态为state2
@Resource State2 state2;
@Override
public String getState() {
return STATE;
}
@Override
public boolean state1(Activity activity) {
log.info("state1 执行完毕 ");
return state2(activity);
}
@Override
public boolean state2(Activity activity) {
super.activityContext.setAbstractState(state2);
return this.activityContext.doWithState2(activity);
}
@Override
public boolean state3(Activity activity) {
return false;
}
}
// ----------------------------------------------------------
// state2
@Component
@Slf4j
public class State2 extends AbstractState {
public static final String STATE = "state2";
// 假设可能的下一个状态为state3
@Resource State3 state3;
@Override
public String getState() {
return STATE;
}
@Override
public boolean state1(Activity activity) {
return false;
}
@Override
public boolean state2(Activity activity) {
log.info("state2 执行完毕 ");
return state3(activity);
}
@Override
public boolean state3(Activity activity) {
super.activityContext.setAbstractState(state3);
return this.activityContext.doWithState3(activity);
}
}
// ----------------------------------------------------------
// state3
@Component
@Slf4j
public class State3 extends AbstractState {
public static final String STATE = "state3";
@Override
public String getState() {
return STATE;
}
@Override
public boolean state1(Activity activity) {
return false;
}
@Override
public boolean state2(Activity activity) {
return false;
}
@Override
public boolean state3(Activity activity) {
log.info("state3 执行完毕 ");
return true;
}
}
3.上下文对象,用以处理不同状态逻辑
public class ActivityContext {
// 上下文对象
private AbstractState abstractState;
public void setAbstractState(AbstractState abstractState) {
this.abstractState = abstractState;
this.abstractState.setActivityContext(this);
}
// 对于所有状态的操作
public boolean doWithState1(Activity activity) {
return this.abstractState.state1(activity);
}
public boolean doWithState2(Activity activity) {
return this.abstractState.state2(activity);
}
public boolean doWithState3(Activity activity) {
return this.abstractState.state3(activity);
}
}
4.一如既往,依赖spring注入来选取对应的state
@Component
public class ActivityFactory {
// map + spring来生成
Map<String, AbstractState> helperMap = new HashMap<>();
@Autowired
public void setHelperMap(List<AbstractState> states) {
helperMap = states.stream().collect(Collectors.toMap(AbstractState::getState, state -> state));
}
public AbstractState getCurState(String state) {
return helperMap.get(state);
}
}
5.测试代码
/**
* @author ChessC
* @version v1.0
* @date 20:00 2021/2/9
*/
@SpringBootTest
@RunWith(SpringRunner.class)
public class StateTest {
@Resource ActivityFactory factory;
@Test
public void test() {
// mock 实体
Activity activity = new Activity().setName("testModel").setState("state1");
// 当前状态
AbstractState curState = factory.getCurState(activity.getState());
// 上下文对象
ActivityContext context = new ActivityContext();
context.setAbstractState(curState);
// 测试状态执行及转换
Assert.assertTrue(context.doWithState1(activity));
}
}
测试结果