Is there such a thing as too many embedded if-statements?

12,427

Solution 1

Technically, I am not aware of any limitation to nesting.

It might be an indicator of poor design if you find yourself going very deep.

Some of what you posted looks like it may be better served as a case statement.

I would be concerned with readability, and code maintenance for the next person which really means it will be difficult - even for the first person (you) - to get it all right in the first place.

edit:

You may also consider having a class that is something like SearchableObject(). You could make a base class of this with common functionality, then inherit for ID, Name, etc, and this top level control block would be drastically simplified.

Solution 2

As Randy mentioned, the cause of this kind of code is in most cases a poor design of an application. Usually I try to use "processor" classes in your case.

For example, given that there is some generic parameter named "operation" and 30 different operations with different parameters, you could make an interface:

interface OperationProcessor {
   boolean validate(Map<String, Object> parameters);
   boolean process(Map<String, Object> parameters);
}

Then implement lots of processors for each operation you need, for example:

class PrinterProcessor implements OperationProcessor {
    boolean validate(Map<String, Object> parameters) {
       return (parameters.get("outputString") != null);
    }
    boolean process(Map<String, Object> parameters) {
       System.out.println(parameters.get("outputString"));
    }
}

Next step - you register all your processors in some array when application is initialized:

public void init() {
    this.processors = new HashMap<String, OperationProcessor>();
    this.processors.put("print",new PrinterProcessor());
    this.processors.put("name_search", new NameSearchProcessor());
    ....
}

So your main method becomes something like this:

String operation = parameters.get("operation"); //For example it could be 'name_search'
OperationProcessor processor = this.processors.get(operation);
if (processor != null && processor.validate()) { //Such operation is registered, and it validated all parameters as appropriate
   processor.process();
} else {
   System.out.println("You are dumb");
}

Sure, this is just an example, and your project would require a bit different approach, but I guess it could be similiar to what I described.

Solution 3

I don't think there is a limit but i wouldn't recommend embeddeding more the two - it's too hard to read, difficult to debug and hard to unit test. Consider taking a look at a couple great books like Refactoring, Design Patterns, and maybe Clean Code

Solution 4

Technically you can have as many as you like but if you have a lot it can quickly make the code unreadable.

What i'd normally do is something like:

if(all_fields_are_empty) {
    abuseuser;
    return;
}

if(id_search() && validId()) {
  //do stuff
  return;
}

if(name_search)
{
  if(name_exists)
    //do stuff
    return
  else
    //do stuff
    return
}

I'm sure you get the picture

Solution 5

Tl;Dr You don't really want anymore than 10-15 paths though any one method

What your essentially referring to here is Cyclomatic complexity.

Cyclomatic complexity is a software metric (measurement), used to indicate the complexity of a program. It is a quantitative measure of the number of linearly independent paths through a program's source code. It was developed by Thomas J. McCabe, Sr. in 1976.

So every if statement is potentially a new path though your code and increases it's Cyclomatic complexity. There are tools that will measure this for you and high light areas of high complexity for potential refactoring.

Is there some standard to how many if statements to embed?

Yes and no. It's generally regarded (and McCabe himself argued) that a Cyclomatic complexity of over about 10 or 15 is too high and a sign that the code should be refactored.

One of McCabe's original applications was to limit the complexity of routines during program development; he recommended that programmers should count the complexity of the modules they are developing, and split them into smaller modules whenever the cyclomatic complexity of the module exceeded 10.[2] This practice was adopted by the NIST Structured Testing methodology, with an observation that since McCabe's original publication, the figure of 10 had received substantial corroborating evidence, but that in some circumstances it may be appropriate to relax the restriction and permit modules with a complexity as high as 15. As the methodology acknowledged that there were occasional reasons for going beyond the agreed-upon limit, it phrased its recommendation as: "For each module, either limit cyclomatic complexity to [the agreed-upon limit] or provide a written explanation of why the limit was exceeded."[7]

This isn't really a hard rule though and can be disregarded in some circumstances. See this question What is the highest Cyclomatic Complexity of any function you maintain? And how would you go about refactoring it?.

why? Is it for readability or is it to keep code running more smoothly?

Essentially this is for readability, which should make your code run smoothly. To quote Martin Fowler

Any fool can write code that a computer can understand. Good programmers write code that humans can understand.

Share:
12,427
Cody
Author by

Cody

Updated on June 04, 2022

Comments

  • Cody
    Cody almost 2 years

    Currently I am working on a bit of code which (I believe) requires quite a few embedded if statements. Is there some standard to how many if statements to embed? Most of my googling has turned up things dealing with excel..don't know why.

    If there is a standard, why? Is it for readability or is it to keep code running more smoothly? In my mind, it makes sense that it would be mainly for readability.

    An example of my if-structure:

    if (!all_fields_are_empty):
        if (id_search() && validId()):
            // do stuff
        else if (name_search):
            if (name_exists):
                if (match < 1):
                    // do stuff
            else:
                // do stuff
        else if (name_search_type_2):
            if (exists):
                if (match < 1):
                    // do stuff
            else:
                // do stuff
    else:
        // you're stupid
    

    I have heard that there's a limit to 2-3 nested for/while loops, but is there some standard for if-statements?

    Update: I have some years under my belt now. Please don't use this many if statements. If you need this many, your design is probably bad. Today, I LOVE when I can find an elegant way to do these things with minimal if statements or switch cases. The code ends up cleaner, easier to test, and easier to maintain. Normally.

  • Cody
    Cody almost 13 years
    I just typed something out really quick as an example of what my if structure was. Part of my python experience coming out, I guess.
  • shevy
    shevy about 4 years
    There may not be an enforced limit, and everyone recommends to keep if-clauses as flat as possible - but I believe this may be a theoretical question. Is the number finite or infinite? I believe it must be a finite number of nested if-clauses before a java program would (have to) crash. Surely it can not be an infinite number ...
  • shevy
    shevy about 4 years
    Are you certain that the number may be infinite, when it comes to nesting? This is more of a theoretical questions, but what if we create a program that keeps on increasing the nesting, until the java compiler could no longer deal with it? But admittedly the answer to such a question would have very llimited usefulness...