代码之家  ›  专栏  ›  技术社区  ›  Anirudh

用java lambda重构许多if-else

  •  -1
  • Anirudh  · 技术社区  · 5 年前

    目前,我正在清理难以维护和测试的杂物,这些杂物是基于隔离中必须检查的条件:

    这些条件的基本语义是什么?

    必须根据两个实体键(即Trans和Right)检查大实体对象的状态变化,如下例所示:

    if (oldTrans.getfOrder().equals(newTrans.getfOrder()) {
         compound.setIsStateChanged(true);
          return;
    }
    if (oldRight.getfRight().equals(newRight.getfRight()) {
         compound.setIsStateChanged(true);
    }
    

    目前,if-else都堆放在一个地方:

        if (oldTrans.getfOrder().equals(newTrans.getfOrder()) {
            compound.setIsStateChanged(true);
            LOGGER.info("major change detected");
            return compound;
        } if (oldTrans.getgOrder().equals(newTrans.getgOrder()) {
            compound.setIsStateChanged(true);
    LOGGER.info("major change detected");
            return compound;   
        }
    

    我在这里看到了两个主要问题

    1. 每个if都有一个return语句,如果有这么多if,很难知道何时退出以及退出哪个point方法。

    2. 对许多人来说,if分支容易出错,条件的数量可能会增加。

    为了避免这么多从干净代码的角度来看基本上基于相同语义的if,我试图用多态的方式来解决它

    将枚举中的条件提取为常量,并实现一个接受新旧对象作为参数的检查器接口

        public interface ICheckStateChange<T>(T old, T new) {
            boolean check(T old, T new);
        }
    
        //implementations
        public TransChecker implements ICheckStateChange<Trans> {
    
          List<BiPredicate<Trans, Trans>> allTransConditions = transConditions.getValues();
    
        public boolean check(Trans oldTrans, Trans newTrans) {
             //all conditions null check here
            //loop through conditions
            for (BiPredicate<Trans, Trans> transCondition: allTransConditions) {
                if (transCondition).test()) {
                    return true;
                 LOGGER.info("major state change detected, taking apt action")
              }
        }
    
    public RightChecker implements ICheckStateChange<Right> {
    
          List<BiPredicate<Right, Right>> allTransConditions = RightConditions.getValues();
    
        public boolean check(Right oldRight, Right newRIght) {
             //all conditions null check here
            //loop through conditions
            for (BiPredicate<Right, Right> rightCondition: allRightConditions) {
                if (rightCondition).test()) {
                    return true;
                 LOGGER.info("major state change detected, taking apt action")
              }
        }
    

    条件现在使用lambdas作为BiPredicate常量位于中心

    public enum rightConditions {
        FORDER_CHANGE_NULL_TO_NOT_NULL((Order old, Order new)
           -> old == null && new != null),
    
        //to be replaced by the right condition
        GORDER_CHANGE_FROM_OPEN_TO_DONE((Order old, Order new)
           -> old == null && new != null)
    
        //to be replaced by the right condition
        LORDER_CHANGE_FROM_OPEN_TO_REVERTED((Order old, Order new)
           -> old == null && new != null)
    
    ........
       }
    

    我在这里的问题是,在干净代码的提示下,如何在lambda BiPredicates的帮助下重构If-elses?可读性、可扩展性和可维护性 ;)

    0 回复  |  直到 5 年前