Monday, September 21, 2009

Software as Literature

Alternative title: Sonnets to CPUs

Have you ever noticed that code follows some basic patterns? JUnit uses Setup(), Test(), Teardown().

I’ve playfully mixed writing and coding below.





//[Play about A Monarch's Destiny, in three acts]
Public KingdomFuture tellTheTaleOfMyRule(Kingdom landMyFatherLeftMe)
{
//[1st Act: Build Drama]
Vassal mySubjects = SoliloquyAboutMyKingdom.getMyPeasants();
Boolean mySubjectsLoyalty = testOfLoyalty(mySubject);

Vassal theCaptainOfTheGuard = SoliloquyAboutMyKingdom.getMyTrustedRightHandMan();
Boolean myTrustedServantsLoyalty = testOfLoyalty(theCaptainOfTheGuard);

KingdomFuture historysTaleOfMyRule = KingdomFuture.UNDECIDED;

//[2nd Act: Drama plays out]
if ( mySubjectsLoyalty == TRUE
&& myTrustedServantsLoyalty == TRUE)
{
HeapPraiseUpon(theCaptainOfTheGuard);
historysTaleOfMyRule = ExpandKingdomByForce(mySubjects);
}
if ( mySubjectsLoyalty == FALSE
&& myTrustedServantsLoyalty == FALSE)
{
ArrestTraitor(theCaptainOfTheGuard);
historysTaleOfMyRule = ImposeDispicableLaws(mySubjects);
}

//[3rd Act: resolve drama]
if ( deceptionHiddenSuccessfully(theCaptainOfTheGuard) )
{
return oldRulerOverthrown;
}
else
{
return historysTaleOfMyRule;
}
}
Delicious Bookmark this on Delicious

Monday, September 14, 2009

Discontinuous Integration

Refactoring is becoming a commonplace term thrown around these days. The expectation is building that refactoring is something that all good developers do and if you don't, you must be in one of "those" types of companies. You know the ones, they don't use a version control system or have a repeatable build, i.e. Continuous Integration, much less a well-defined deployment procedure.

If you are lucky enough to be building the first version of a product, you can refactor to your hearts content. There is no existing code to worry about breaking. If you are changing an existing system refactoring isn't always simple or straightforward. Even if you have the most automated CI and 100% code coverage of unit tests you'll still face the practical issues of deployment and business dependencies.

Let's say you operated the worlds most modern airline reservation system. It's written in the latest language and has all the buzzwords, highly available, highly reliable, highly scalable, etc. It has tons of automated tests so you are 100% confident that nothing will break. Now, since you have business partners like travel agencies and customers looking to book a flight or retrieve flight information, they have a stake in your deployment. The customers may tolerage a "Down for maintenencem, come back later." message but your partners will take a dim view of your downtime. They'll insist you tell them in advance so they can prepare any necessary changes in their systems or alert their support staff in case there are issues after the deployment.

Another example would be a large back-office accounting system. Whatever level of confidence you have in your code. you still have to deal with the myriad inputs and outputs of the system and disrupting the processing schedule for a code migration. No amount of automated testing/build/migration will ever solve these types of complexities.

The point is that considerations like these limit the opportunities to deploy code changes and increase the cost of change even when that change is guaranteed to work.

Refactoring is good but there are practical considerations why it's not done to the degree it could be in some shops. Keep that in mind next time you want to pass judgement on the perceived lack of refactoring somewhere.
Delicious Bookmark this on Delicious