views:

142

answers:

5

I have a simple method that returns bool, but it internally loads various objects.

I check for null for each, but it becomes very ugly.

Is there a better way?

public bool SomeTest(int id1)
{
   bool result = false;

   User user = userDao.GetById(id1);

   if(user != null)
   {
      Blah blah = blahDao.GetById(user.BlahId);


     if(blah != null)
     {
         FooBar fb = fbDao.GetById(blah.FooBarId);

         if(fb != null)
         {
           // you_get_the_idea!

         }


     }
   }


   return result;
}

Is there a pattern that could make this a more inline instead of nested if's?

+2  A: 

seriously?

Blah blah = GetBlah();
if (blah == null) return false;
pm100
There's no technical difference between this answer at -1 and Jon's at +7. +1 from me.
Joel Mueller
+15  A: 

Does it need to do anything other than check whether the entity exists? I'll assume not.

First step: ignore the "one exit point" rule and reduce nesting:

public bool SomeTest(int id1)
{
   User user = userDao.GetById(id1);    
   if (user == null)
   {
      return false;
   }

   Blah blah = blahDao.GetById(user.BlahId);
   if (blah == null)
   {
       return false;
   }

   FooBar fb = fbDao.GetById(blah.FooBarId);
   if (fb == null)
   {
       return false;
   }

   return true;
}

What comes next is likely to be language-specific... what language are you using, and which version of the platform? Can you alter your DAOs? C# has a bit more language flexibility (lambda expressions, the null coalescing operator, things like that) which may be handy in this situation.

Jon Skeet
+1 for 'First step: ignore the "one exit point" rule and reduce nesting'Some of the most unreadable code I've seen is done in the name of the one exit point rule :)
Rob Levine
+1  A: 

Perhaps:

User user;
Blah blah;
FooBar fb;
if( (user = userDao.GetById(id1)) != null
 && (blah = blahDao.GetById(user.BlahId)) != null
 && (fb   = fbDao.GetById(blah.FooBarId)) != null)
{
    // set flag, manipulate user/blah/fb, etc
}
Marc Gravell
+5  A: 

Assuming there's nothing you can do to recover, you could just return as soon as you get a null:

User user = UserDAO.GetById(id1);

if(user == null) return false;

Blah blah = blahDao.GetById(user.BlahId);

if(blah == null) return false;

You might also want to look at the Null object pattern

Lee
+1 for the Null Object Pattern reference. It may be very helpful depending upon the context of the problem.
Austin Salonen
+1  A: 

To add to all other answers, if you had an IDao interface for instance

public interface IDao
{
   bool CanGetUser(int id);
}

Then you can pass in a List of DAO's created somewhere else.

public bool SomeTest(int id1, IEnumerable<IDao> daoList)
{
   return daoList.Any( dao => dao.CanGetUser(id1) );
}
Stan R.