The argument is "are guard clauses in methods okay?" And how do you handle resource cleanup if one of the guard clauses fail? I haven't seen a convincing consensus either way. A specific example: Let's say you have 10 resources to allocate (like opening files, networks, etc) -- for brevity here, let's just use four resources. All resources have to be allocated for the method to continue. So what we are trying to avoid is something like this (yuck):
isMethodSuccessful = false; // assume this isn't going to work
resource1 = OpenMyFile(myFile);
if (resource1 == SUCCESS)
{
resource2 = OpenSomeNetworkConnection(networkID)
if (resource2 == OKAY)
{
resource3 = CreateNewFile(outputFile);
if (resource3 == SUCCESS)
{
resource4 = ConnectToSomething(mySomething);
if (resource4)
{
//
// Do all my logic here
//
isMethodSuccessful = true; // return success
}
else
{
DeleteFile(resource3); // do cleanup
CloseNetwork(resource2);
CloseFile(resource1);
}
}
else
{
CloseNetwork(resource2); // do cleanup
CloseFile(resource1);
}
}
else
{
CloseFile(resource1); // do cleanup
}
return (isMethodSuccessful);
}
Guard clauses will convert that mess into something like this:
resource1 = OpenMyFile(myFile);
if (resource1 != SUCCESS)
{
return failure;
}
resource2 = OpenSomeNetworkConnection(networkID)
if (resource2 != OKAY)
{
CloseFile(resource1); // do cleanup
return failure;
}
resource3 = CreateNewFile(outputFile);
if (resource3 != SUCCESS)
{
CloseNetwork(resource2); // do cleanup
CloseFile(resource1);
return failure;
}
resource4 = ConnectToSomething(mySomething);
if (!resource4)
{
DeleteFile(resource3); // do cleanup
CloseNetwork(resource2);
CloseFile(resource1);
return failure;
}
//
// Put all your logic here
//
return (success);
...which is far from ideal (i.e. more yuck). So what's the best code logic in this situation?