• 策略模式应用审批


    需求如图

     
    需要依据动作 来执行 状态的改变
    最开始 写法:
     
    public enum AuditActionEnum {

    commit("commit", "提交审核"),
    approvePass("approvePass", "审核通过"),
    approveReject("approveReject", "审核拒绝");

    private String key;
    private String desc;

    AuditActionEnum(String key, String desc) {
    this.key = key;
    this.desc = desc;
    }

    public String getKey() {
    return this.key;
    }
    public String getDesc() {
    return this.desc;
    }

    public static AuditActionEnum match(String key) {
    for (AuditActionEnum e : AuditActionEnum.values()) {
    if (e.getKey().equals(key)) {
    return e;
    }
    }
    return null;
    }
    }

    通过状态:来做对应的数据库处理
    if (AuditActionEnum.commit.getKey().equals(auditAction)) {
    updateWrapper.set("audit_state", AuditStateEnum.committed.getKey());
    updateWrapper.set("commit_time", auditCommitResDto.getCommitTime() == null ? DateUtil.getCurrentDatetime() : auditCommitResDto.getCommitTime());
    }
    if (AuditActionEnum.approvePass.getKey().equals(auditAction)) {
    updateWrapper.set("is_master", EffectMasterEnum.master.getKey());
    updateWrapper.set("is_effective", EffectMasterEnum.effect.getKey());
    updateWrapper.set("audit_time", auditCommitResDto.getAuditTime() == null ? DateUtil.getCurrentDatetime() : auditCommitResDto.getAuditTime());
    updateWrapper.set("audit_id", auditCommitResDto.getAuditId());
    updateWrapper.set("audit_state", auditCommitResDto.getAuditState());
    }
    if (AuditActionEnum.approveReject.getKey().equals(auditAction)) {
    updateWrapper.set("is_master", EffectMasterEnum.master.getKey());
    updateWrapper.set("is_effective", EffectMasterEnum.un_effect.getKey());
    updateWrapper.set("audit_time", auditCommitResDto.getAuditTime() == null ? DateUtil.getCurrentDatetime() : auditCommitResDto.getAuditTime());
    updateWrapper.set("audit_state", auditCommitResDto.getAuditState());
    updateWrapper.set("audit_id", auditCommitResDto.getAuditId());
    }
     
    写完之后觉得不妥 太多 if else
    改为 使用策略模式:
     
     策略接口:
    @Component
    public interface IAuditStrategy {
    void doAction(IService service , Long id , AuditCommitResDto auditCommitResDto);
    }

    @Component("commit")
    public class CommitAuditStrategy implements IAuditStrategy {
    @Override
    public void doAction(IService service, Long id, AuditCommitResDto auditCommitResDto) {
    service.update(new UpdateWrapper<>()
    .set("audit_id", auditCommitResDto.getAuditId())
    .set("commit_time", auditCommitResDto.getCommitTime())
    .set("audit_state", auditCommitResDto.getAuditState())
    .eq("id", id)
    );
    }
    }

    具体实现子类:
    @Component("approvePass")
    public class ApprovePassAuditStrategy implements IAuditStrategy {
    @Override
    public void doAction(IService service, Long id, AuditCommitResDto auditCommitResDto) {
    //审核通过先把之前数据失效 ,在把通过的这条生效
    service.update(new UpdateWrapper<>()
    .set("is_effective", EffectMasterEnum.effect.getKey())
    .eq("master_id", id)
    );
    service.update(new UpdateWrapper<>()
    .set("is_effective", EffectMasterEnum.effect.getKey())
    .set("audit_time", auditCommitResDto.getAuditTime())
    .set("audit_state", auditCommitResDto.getAuditState())
    .eq("id", id)

    );
    }
    }
     
     
    通过 ioc 容器注入 并调用:
     
    @Autowired
    private Map<String, IAuditStrategy> auditStrategyMap;


    调用代码:
    auditStrategyMap.get(dto.getAuditAction()).doAction(this,id,auditCommitResDto);
     
     ======================================================================================= 经好友提示直接使用 String 作为策略的key容易与其他bean 冲突  所以使用 枚举类作为 key较好,这里引用 
    ApplicationContextAware 
    好处是不用重新 加载一遍 上下文 applicationContext (如直接用
    ApplicationContext appContext = new ClassPathXmlApplicationContext("applicationContext-common.xml");  
    AbcService abcService = (AbcService)appContext.getBean("abcService");  
    因为它会重新装载applicationContext-common.xml并实例化上下文bean,如果有些线程配置类也是在这个配置文件中,那么会造成做相同工作的的线程会被启两次。一次是web容器初始化时启动,另一次是上述代码显示的实例化了一次。当于重新初始化一遍!!!!这样就产生了冗余。


    所以新增一个工厂类 去注册策略的生成
    @Component
    public class IAuditStrategyFactory implements ApplicationContextAware {
    private Map<AuditActionEnum, IAuditStrategy> iAuditActionStateMap = new ConcurrentHashMap<>();
    public IAuditStrategy getStrategy(AuditActionEnum auditActionEnum) {
    return iAuditActionStateMap.get(auditActionEnum);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    Map<String, IAuditStrategy> map = applicationContext.getBeansOfType(IAuditStrategy.class);
    for(Map.Entry<String, IAuditStrategy> entry:map.entrySet()){
    iAuditActionStateMap.put(AuditActionEnum.match(entry.getKey()), entry.getValue());
    }
    }
    }
     
     
     
  • 相关阅读:
    各种页的意义
    ecstore Fatal error: Class 'base_request' not found
    viewer.js 视图预览demo
    div在另一个div居中对齐
    文件权限解释rwx
    TPshop各个目录模块介绍
    tpshop linux安装下注意事项
    navicate 远程无法链接linux上mysql数据库问题
    关于破解邮箱的一点心得
    linux开启新端口
  • 原文地址:https://www.cnblogs.com/publicmain/p/16202304.html
Copyright © 2020-2023  润新知