Help reorganize this messy-nested if method

Ok, I need some opinions on how I can fix this method mess!

It has WAY for many nested if statements.

But understand that I must know exactly where the method fails, currently in each of the corresponding else clause. I am logging an error (failed if condition).

Note: ignore any logic related to things, please focus on style and structure as I created all function names, etc.

Here is the structure of the skeleton:

   public void MyMethod()
{

   try
   {
    bool tryAgain = false;

    string filename = DownloadFile();

    if( IsFileFormatOk(filename) )
    {

        blah = GetBlah(filename);

        if(blah.ID > 0)
        {

            if(ImportFile(filename)
            {

                string username = GetUserFromFile(filename);

                if(isValidUser(username))
                {

                    // few more levels to go
                    //
                    //
                    //

                }
                else
                {
                    LogError(filename, ...); // specific to this if statement
                    tryAgain = true;
                }


            }
            else
            {

                LogError(filename, ...); // specific to this if statement
                tryAgain = true;
            }

        }
        else
        {
            LogError(filename, ...); // specific to this if statement
            tryAgain = true;
        }

    }
    else
    {
        LogError(filename, ...); // specific to this if statement
        tryAgain = true;
    }

   }
   catch
   {
   }
   finally
   {
    if(tryAgain)
    {
        // blah
    }
   }


}
+3
source share
7 answers

I would work on changing the logic so that you can return from the method as soon as possible, rather than nesting more logic. Example:

//  GOOD
if (!file.exists())
    return;
// Rest of the code

// BAD
if (file.exists()){
    // Code goes here
}
return;

.

+5

, , , , :

try
{
  if( !IsFileFormatOk(filename) )
    throw new MySpecificException(...); // pass specific log params

  blah = GetBlah(filename);

  if(blah.ID <= 0)
    throw new MySpecificException(...); // pass specific log params

  if(!ImportFile(filename)
    throw new MySpecificException(...); // pass specific log params

  string username = GetUserFromFile(filename);

  // ...
}
catch (MySecificException e)
{
  LogError(filename, e.LogParams)
  // blah
}
+3

, toplevel if (true branch) . .

, :

if (condition) {
  // Block1
} else {
  // Block2
}

if (condition) {
  Block(...);
} else {
  Block2(...);
}

, .

+1

: , , , . , " ", , , . , ( - , ). if.

if(EndOfWorld)
{
    WriteLastLogEntryEver();
    return; //run away
}

//we're safe (for now)
ChargeOnAhead();

, , if, .

public void MyMethod()
{

   try
   {
    bool tryAgain = false;

    string filename = DownloadFile();

    if( IsFileFormatOk(filename) )
    {

        tryAgain = DoBlah(filename, ...);
    }
    else
    {
        LogError(filename, ...); // specific to this if statement
        tryAgain = true;
    }

   }
   catch
   {
   }
   finally
   {
    if(tryAgain)
    {
        // blah
    }
   }


}

private bool DoImport(string filename, blah)
{

    if(ImportFile(filename))
    {

            // and so forth!
            return false;
    }

    LogError(filename, ...); // specific to this if statement
    return true;
}

private bool DoBlah(string filename)
{
        blah = GetBlah(filename);

        if(blah.ID > 0)
        {

            return DoImport(filename, ...);

        }

        LogError(filename, ...); // specific to this if statement
        return true;

}

, // and so forth . , . , , .


0

, , , . , . LogError(), . ():

MyMethod()
{
  try
  {
    string filename = DownloadFile()
    blah = GetBlah(filename)
    ImportFile(filename)
    ...
  }
  catch DownloadFileException, GetBlahException, ImportFileException e
  {
    LogError(e)
  }
}

Of course, you will have to create all of these Exceptions, but this is pretty trivial. In most languages, you simply subclass any top-level Exception object.

0
source

Here's the jjnguy suggestion implemented:

public void MyMethod() {
    try
    {
        bool tryAgain = false;
        string filename = DownloadFile();

        if( !IsFileFormatOk(filename) )
        {
            LogError(filename, ...); // specific to this if statement
            tryAgain = true;
            return;
        }

        blah = GetBlah(filename);
        if(blah.ID <= 0)
        {
            LogError(filename, ...); // specific to this if statement
            tryAgain = true;
            return;
        }

        if(!ImportFile(filename))
        {
            LogError(filename, ...); // specific to this if statement
            tryAgain = true;
            return;
        }

        string username = GetUserFromFile(filename);

        if(!isValidUser(username))
        {
            LogError(filename, ...); // specific to this if statement
            tryAgain = true;
            return
        }

        // few more levels to go
        //

    finally
    {
        if(tryAgain)
        {
            // blah
        }
   }
}
0
source

For this kind of questions, http://refactormycode.com/ is very helpful.

Although SO people are really committed to refactoring some code .;)

0
source

All Articles