Thursday, 21 January 2010

The LIBUSWKAIQ anti-pattern

Design patterns have been all the rage for quite some time now, and with them have come an increased awareness of patterns that pretend to be design patterns but really are anti-patterns; a pattern that appears obvious but really is far from optimal in practice (read: stupid).

A relatively recent (and greenfield) implementation where I work is built around such an anti-pattern. We've named this lovely piece of instant legacy the LIBUSWKAIQ anti-pattern. It's pronounced "Libbus-wah-cake" and stands for "Let It Blow Up So We Know About It Quickly."

  • This pattern gives you free license to forget about exception handling and encourages applications to fall over and die if any exceptional circumstances arise.
  • This pattern encourages you to throw exceptions with the explicit purpose of killing your app.
  • This pattern hates error handling.
  • This pattern creates needy applications that require immediate attention.
  • This pattern encourages 3am support calls. This pattern wants your support developers to always be deprived of sleep. This patterns wants you to spend your ENTIRE support budget.
  • This pattern appeals to lazy people.

Don't do this! Handle your errors. Keep your apps running. Put errors to the side and let humans deal with it as soon as it is conveniently possible. Don't stop your entire business process running just because it experienced a minor 'blip.'

You're smarter than this. Don't get sucked into becoming a Libbus-wah-caker.

3 comments:

eugoogoolizer said...

Could we have some more detail on this please? Do you have any UML for it?

Scott Millett said...

Interesting post, I always change my mind on this point “This pattern encourages you to throw exceptions with the explicit purpose of killing your app.”

Take this simple example.....

Class BankAccount
{
Public bool CanWithdrawal(decimal amount)
{
// Logic to work out if we can withdrawal the amount .....
}

Public void Withdrawal(decimal amount)
{
If (CanWithdrawal(amount))
{
// all good...
}
else
{
// No cash!!
throw new LackOfFundsException();
}
}


How would you alter the code or would you include the exception?

I am relying on users of the class to adopt the Tester-Doer pattern i.e.


If (myBankAccount.CanWithdrawal(amountToWithdrawal))
{
myBankAccount.WithDrawal(amountToWithdrawal);
}


I would be interested to hear your thoughts on this.

Of course if I was using this behind a service I would use the exception shielding pattern that you mentioned in your blog post a while back.

The book Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Libraries has one of the best chapters I have read on exceptions.
Cheers
Scott

Øyvind Valland said...

Hi Scott,

Thanks for your comment. Your example shows valid use of exceptions, and I've nothing against it. However, Libbus-wah-cake, as I try to describe it, doesn't want you to use exceptions sensibly in the way that you've described. This 'pattern' ensures that exceptions are always allowed to bubble right up to the runtime. They are unhandled, thereby causing any app built in this manner to die once an exception is thrown.

I think that is exceptionally poor practice (pun intended), particularly because the way in which I've seen it applied is just a dirty shortcut to avoid doing proper error handling and alerting.