简体   繁体   中英

Reduce The Boolean Expression Complexity of this method?

This isValid() method has up to 6 attributes that can be set in order to be validated. If a particular attribute isn't set, it doesn't need to be validated. The logic appears to be working just how I would like it to work. How can I reduce the boolean expression complexity of this method?

import java.util.ArrayList;
import java.util.List;

public class Valid {

private int foo;
private int bar;
private int foobar;
private String foofoo;
private String barbar;
private String foobarfoobar;

private int myfoo;
private int mybar;
private int myfoobar;
private String myfoofoo;
private List<String> mybarbarlist = new ArrayList<String>();
private String myfoobarfoobar;

private boolean validate;

public boolean isValid() {

    validate = false;

    if ((((foo > 0) && (foo == myfoo)) || (foo == 0))
            && (((bar > 0) && (bar == mybar)) || (bar == 0))
            && (((foobar > 0) && (foobar == myfoobar)) || (foobar == 0))
            && (((foofoo != null) && (foofoo.equals(myfoofoo))) || (foofoo == null))
            && (((barbar != null) && (mybarbarlist.contains(barbar))) || (barbar == null))
            && (((foobarfoobar != null) && (foobarfoobar
                    .equals(myfoobarfoobar))) || (foobarfoobar == null)))
        validate = true;
    return validate;
}

public static void main(String[] args) {

    Valid valid = new Valid();

    // valid.foo = 1;
    // valid.bar = 1;
    // valid.foobar = 1;
    // valid.foofoo = "1";
    // valid.barbar = "1";
    // valid.foobarfoobar = "1";

    // valid.myfoo = 1;
    // valid.mybar = 1;
    // valid.myfoobar = 1;
    // valid.myfoofoo = "1";
    // valid.mybarbarlist.add("1");
    // valid.myfoobarfoobar = "1";

    System.out.println(valid.isValid());
}
}

I would start by giving meaningful names to each sub-expression and assign the results to variables and then do an && check between the variables. This will greatly increase readability.

Also your conditions all seem to have the form

(X != null && X == value) || X == null

which can be simplified using short-circuit evaluation to just

X == null || X == value

since if X == null evaluates true then it doesn't need to check the right side, or if X == null evaluates false and it needs to check the right side you already know its not null so you don't need to check for null in the expression on the right side.

Combining the two you would get something like this:

public boolean isValid() {

    validate = false;

    boolean fooCond = (foo == 0) || (foo == myfoo);
    boolean barCond = (bar == 0) || (bar == mybar);
    boolean foobarCond = (foobar == 0) || (foobar == myfoobar);
    boolean foofooCond = (foofoo == null) || foofoo.equals(myfoofoo);
    boolean barbarCond = (barbar == null) || mybarbarlist.contains(barbar);
    boolean foobarfoobarCond = (foobarfoobar == null) || foobarfoobar.equals(myfoobarfoobar);

    if (fooCond
          && barCond
          && foobarCond
          && foofooCond;
          && barbarCond
          && foobarfoobarCond) {
        validate = true;
    }

    return validate;
}

EDIT

This doesn't quite work for your expressions where you are checking

((foo > 0) && (foo == myfoo)) || (foo == 0)

since if foo < 0 it returns false. If you really meant

((foo > 0) && (foo == myfoo)) || (foo <= 0)

then this method works as written.

I would recommend reading about boolean algebra and simplifying boolean expressions. There are multiple ways of doing it, whether it be Karnaugh maps or simply using algebraic laws.

You can check out this which will give you a basic insight of what it's about. In relation to your code, I would recommend jotting down a truth table, and working out the truth values for when your method returns true. From there grab your current equation and simplify it as much as possible


To also give you an example of how simplification works: 在此处输入图片说明

A XOR B = A & !B OR !A & B

The left hand side if the simplified expression of the right hand side


For a list of laws that will definitely help you, check out Boolean Algebra Laws

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM