Tags: code

glasses

Implementation resilience

I've started thinking about resilience of the implementations of the methods that I write, defined as the likelihood that if I add or remove something from that method, will it work without having to make other modifications?  Here's a simple example.  Say you're in the unfortunate circumstance of being in a C++ code base that doesn't allow the use of exceptions.  You might write:

HRESULT hr = S_OK;
hr = DoSomething();
if ( FAILED(hr) ) cout << "uh oh!";
return hr;

Even though the initial assignment to hr is not useful, the compiler will optimize it away.  The point is it's more resilient to change than:

HRESULT hr = E_FAIL;
hr = DoSomething();

if ( FAILED(hr) ) cout << "uh oh!";
return hr;

In this example, hr is fail-by-default, which matters if DoSomething() is ever removed, because then the function will be returning failure when it succeeded. 

I think of the initialization as the base case... if you do it right, the induction steps work.  Do it wrong and it all breaks down.

Another example regards early returns, which typically should be avoided except for in error conditions.
bool isFooey = IsFooey();
if ( isFooey ) return true;
DoStuffDoneLessOfTheTime();
bool isMooey = IsMooey();
if ( isMooey ) return true;
DoStuffDoneEvenLessOfTheTime();
return false;

When adding code to this function, it's not enough to just know which method to put it in, I have to carefully craft where in this method to do it. I've gotta scan the whole function to understand the control flow, which is problematic if the method is long.  The best case for a programmer is to be able to get in and get out while understanding as little of his surroundings as possible.

If I had to keep all of this as one function, I would refactor this so that there's effectively one branching point in the flow.  Doing it as a switch makes this clearest, though admittedly that may or may not be contrived depending on the circumstance.
DoStuffDoneAllTheTime();
enum FooMoo fm = GetFooeyMooeyNess();
switch ( fm )
{
case Fooey:
   return true;
case Mooey:
   DoStuffDoneLessOfTheTime();
   return true;
default:
   DoStuffDoneLessOfTheTime();
   DoStuffDoneEvenLessOfTheTime();
   return false;
}

Any thoughts?
  • Current Music
    Antony DeGenarro - Atmospheres
  • Tags