DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
  1. DZone
  2. Culture and Methodologies
  3. Career Development
  4. How to Deal With Nested Conditionals (Part 1)

How to Deal With Nested Conditionals (Part 1)

It's fun looking over thousands of lines of code to see if-else statements wrapped in if-else statements, right? No. Here's how to approach refactoring nested conditionals.

Suleyman Yildirim user avatar by
Suleyman Yildirim
·
Feb. 15, 17 · Tutorial
Like (9)
Save
Tweet
Share
10.85K Views

Join the DZone community and get the full member experience.

Join For Free

In my current project, there are thousands of lines of code (LOC), some of which date back to 10 years ago. An important part of my day-to-day job is trying to understand and debug functions just like the following example (Listing 1). I omitted the boolean expressions and the code in branches, but there is still something wrong with it!

Listing 1:
public Response
function() {
    if () {
        if ()
            if () {
                if () {
                    if () {
                        for () {
                            if () {
                                if () {}
                            }
                        }
                    } else {}
                }
            } else {
                if () {
                    if () {}
                    if () {
                        for () {
                            // Line 21: see the code in listing 2
                            if () {
                                if () {}
                            }
                            // Line 26: see the code in listing 2 
                        }
                        if () {}
                    } else {}
                } else {
                    // Line 33: see the code in listing 3
                    if () {
                        if () {
                            if () {
                                // Line 37: see the code in listing 3
                                if () {}
                                if () {}
                                if () {
                                    if () {
                                        if () {
                                            if () {
                                                if () {
                                                    if () {
                                                        if () {}
                                                        if () {}
                                                    }
                                                } else {}
                                            } else {}
                                        } else {}
                                    }
                                } else {}
                            }
                        } else if () {
                            if () {
                                if () {
                                    if () {
                                        if () {
                                            if () {}
                                        }
                                        if () {
                                            if () {
                                                if () {} else {}
                                                if () {} else {}
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
    } else
    if () {}
    return response;
}


You might think, "What's the problem? If it's working, it's fine!" Indeed, it is working but:

  • Is it easy for you to read it?

  • Can you understand the execution flow?

  • What if you add new functionality to that function? Are you sure that you won't break existing requirements?

  • Have you heard of "cyclomatic complexity?"

  • How testable is that function?

I think somebody knows the answers: "Any fool can write code that a computer can understand. Good programmers write code that humans can understand," Martin Fowler, 2008.

The original code, 412 LOC in total, is much more complex in terms of readability and maintainability. There are multiple boolean expressions in almost every if statement; such as the code in Listing 2:

Listing 2:
if (retrieveIndividualCustomerAddressInfoResponse.getAddresses()[a].getContactType() != null && retrieveIndividualCustomerAddressInfoResponse.getAddresses()[a].getContactType().getValue() == SubContactTypeCS.POSTAL_ADDRESS) {
    if (retrieveIndividualCustomerAddressInfoResponse.getAddresses()[a].getPartyRoleInContactPointType() != null && retrieveIndividualCustomerAddressInfoResponse.getAddresses()[a].getPartyRoleInContactPointType().getValue() == PartyRoleInContactPointTypeCS.HOME) {
        ...
    }
}


Decompose Conditional

We can start refactoring with complicated conditionals. Extract methods for each boolean expression as follows. The result is still nested, but there is another technique — consolidating conditional expressions — that will help.

if (isValidContactType()) {
    if (isValidPartyRoleInContactPointType()) {
        ...
    }
}
private boolean isValidContractType(){
    return retrieveIndividualCustomerAddressInfoResponse.getAddresses()[a].getContactType() != null && retrieveIndividualCustomerAddressInfoResponse.getAddresses()[a].getContactType().getValue() == SubContactTypeCS.POSTAL_ADDRESS;
}

private boolean isValidPartyRoleInContactPointType(){ 
    return retrieveIndividualCustomerAddressInfoResponse.getAddresses()[a].getPartyRoleInContactPointType() != null && retrieveIndividualCustomerAddressInfoResponse.getAddresses()[a].getPartyRoleInContactPointType().getValue() == PartyRoleInContactPointTypeCS.HOME; 
}


Consolidate Conditional Expression

Another attempt to eliminate nested if-else statements could be combining multiple conditionals into a single conditional expression and extracting it; such as the code in Listing 3:

Listing 3:
if (customerType != Constants.CUSTOMERID) {
    if (customerType == Constants.XXX) {
        ...      
        if (retrieveCitizenResponse != null && retrieveCitizenResponse.getCitizen() != null) {
            ...
        }
    }
}


Step 1: Consolidate Conditionals Into One Statement

Listing 3 Step 1:
if (customerType != Constants.CUSTOMERID && customerType == Constants.XXX && retrieveCitizenResponse != null && retrieveCitizenResponse.getCitizen() != null) {
}


Step 2: Decompose Conditionals Into Relevant Functions

Listing 3 Step 2:
if (getCustomerType() && retrieveCitizenResponse()) {
  ...
}
private boolean getCustomerType (){ 
   return customerType != Constants.CUSTOMERID && customerType == Constants.XXX;
} 
private boolean retrieveCitizenResponse(){
   return retrieveCitizenResponse != null && retrieveCitizenResponse.getCitizen() != null;
}
IT Listing (computer) Execution (computing) career Debug (command) Programmer (hardware) Extract

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • A Beginner's Guide to Back-End Development
  • Integration: Data, Security, Challenges, and Best Solutions
  • How To Convert HTML to PNG in Java
  • How Observability Is Redefining Developer Roles

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: