How to split up complex conditions and keep short circuit evaluation?

前端 未结 11 1816
清歌不尽
清歌不尽 2020-12-17 16:55

Sometimes conditions can become quite complex, so for readability I usually split them up and give each component a meaningful name. This defeats short-circuit evaluation ho

相关标签:
11条回答
  • 2020-12-17 17:28

    The BooleanExpression type doesn't seem to be useful enough to be a class on its own outside your main class and it adds some intellectual weight to your application too. I would simply just write private methods that are named appropriately to run the checks you want. It's much simpler.

    0 讨论(0)
  • 2020-12-17 17:34

    Your first solution is good for this kind of complexity. If the conditions were more complex, I would write private methods for each check you need to run. Something like:

    public class DemoStackOverflow {
    
        public static void main(String[] args) {
        if ( areValid(args) ) {
            System.out.println("Arguments OK");
        }
        }
    
        /**
         * Validation of parameters.
         * 
         * @param args an array with the parameters to validate.
         * @return true if the arguments are not null, the quantity of arguments match 
         * the expected quantity and the first and second are not equal; 
         *         false, otherwise.
         */
        private static boolean areValid(String[] args) {
           return notNull(args) && lengthOK(args) && areDifferent(args);
        }
    
        private static boolean notNull(String[] args) {
           return args != null;
        }
    
        private static boolean lengthOK(String[] args) {
           return args.length == EXPECTED_ARGS;
        }
    
        private static boolean areDifferent(String[] args) {
           return !args[0].equals(args[1]);
        }
    
        /** Quantity of expected arguments */
        private static final int EXPECTED_ARGS = 2;
    
    }
    
    0 讨论(0)
  • 2020-12-17 17:36

    You must do the variable assignment INSIDE the if's.

    if (a && b && c) ...
    

    translates to

    calculatedA = a;
    if (calculatedA) {
      calculatedB = b;
      if (calculatedB) {
        calculatedC = c;
        if (calculatedC) ....
      }
    }
    

    It is often beneficial to do this anyway since it names the concepts you are testing for, as you demonstrate clearly in your example code. This increases readability.

    0 讨论(0)
  • 2020-12-17 17:37

    You can use early returns (from a method) to achieve the same effect:

    [Some fixes applied]

      public static boolean areArgsOk(String[] args) {
         if(args == null)
            return false;
    
         if(args.length != 2)
            return false;
    
         if(args[0].equals(args[1]))
            return false;
    
         return true;
      }
    
      public static void main2(String[] args) {
    
            boolean b = areArgsOk(args);
            if(b)
               System.out.println("Args are ok");
      }
    
    0 讨论(0)
  • 2020-12-17 17:38

    Split it out into a separate function (to improve readability in main()) and add a comment (so people understand what you are trying to accomplish)

    public static void main(String[] args) {
        if (argumentsAreValid(args)) {
                System.out.println("Args are ok");
        }
    }
    
    
    public static boolean argumentsAreValid(String[] args) {
        // Must have 2 arguments (and the second can't be the same as the first)
        return args == null || args.length == 2 || !args[0].equals(args[1]);
    }
    

    ETA: I also like Itay's idea of using early returns in the ArgumentsAreValid function to improve the readability.

    0 讨论(0)
  • 2020-12-17 17:39

    There's really nothing wrong with the first piece of code; you're overthinking things, IMO.

    Here's another way that, while verbose, is easy to understand.

    static void usage() {
        System.err.println("Usage: blah blah blah blah");
        System.exit(-1);
    }
    
    // ...
    
    if (args == null || args.length < 2)
        usage();
    if (args[0].equals(args[1]))
        usage()
    
    0 讨论(0)
提交回复
热议问题