Refactored these overloaded CreateLoanApplicant methods, and there were more than one thousand lines of code in each method. Most business logic had been simply copied, pasted, and slightly modified somewhere in these overloaded CreateLoanApplicant methods. One of these methods looks like code below.

public LoanApplicantResponse CreateLoanApplicant(ApplicantInfo applicant) 
{
    LoanApplicantResponse response = new LoanApplicantResponse();

    // business logic #1
    if (condition1 == false)
    {
        // log the error           
        return response;
    }

    // business logic #2
    try
    {
        // process data, modify response
    }
    catch (CustomException1 ex1) 
    {
        // log the error           
        return response;
    }
    catch (CustomException2 ex2) 
    {
        // log the error only 
    }
    catch (Exception ex) 
    {
        // log the error only 
    }
    
    // ...

    // business logic #20

    return response;
}

 

Observations:

  1. There are over one  thousand lines of code in this method.
  2. There are 20 different business logic
  3. If the error is not so severe, simply log the error and proceed to next step.
  4. If the error is severe, log the error and return the response

 

First round of refactoring goal is to simply extract each business logic into a method without spending lot of time on studying and modifying each business logic.

Refactoring steps:
1. Null Object. Create a NullLoanApplicantResponse class

public class NullLoanApplicantResponse : LoanApplicantResponse

2. Use Visual Studio ‘Extract Method’ to extract each business logic. The structure of each business logic looks similar to code below.

private static LoanApplicantResponse ProcessBusinessLogic1(
    ApplicantInfo applicant, LoanApplicantResponse response)
{
    if (condition1 == false)
    {
        // log the error           
        return response;
    }

    return new NullLoanApplicantResponse();
}

3. The code looks like after 1st round of refactoring.

public LoanApplicantResponse CreateLoanApplicant(ApplicantInfo applicant) 
{
    LoanApplicantResponse response = new LoanApplicantResponse();
    LoanApplicantResponse methodResponse;
    
    // business logic #1
    methodResponse = ProcessBusinessLogic1(applicant, response);  
    if (methodResponse.IsNull() == false)
    {         
        return response;
    }

    // business logic #2
    methodResponse = ProcessBusinessLogic2(applicant, response);  
    if (methodResponse.IsNull() == false)
    {         
        return response;
    }

    // ...

    // business logic #20
    methodResponse = ProcessBusinessLogic20(applicant, response);  
    if (methodResponse.IsNull() == false)
    {         
        return response;
    }

    return response;
}

 

It immediately cut down the line of code in this method to a manageable size of less than one hundred, and it is much easier to understand.

Also note that the structure of each business logic looks similar. There are  further refactoring opportunities that we will discuss later in more refactoring tips.

 

Advertisements