I got probably the biggest compliment I've ever received regarding my coding ability the other day in the form of a twitter entry (a "tweet"...I guess...is the word.  /puke) by my junior programmer and right hand man boy, that (aka Doug, bct).

good api's make things easy. sweet api's are self explanitory, imo. i got to work with a sweet one today. thx scott.

He was talking about the internal library I created for working with Word documents, part of which I published for a series of blog posts a couple of months ago.  I bring this up not to toot my own horn (well, maybe a little), but to illustrate a point regarding code reuse.

This blog post showed up in RSSBandit today that references an old article by Dennis Forbes, the basic gist of which is that code reuse for the sake of saying you have "code reuse" is the domain of the feeble minded and self-indulgent.  On that much, I agree.  The real villain here is not the idea of reusable code libraries, it's the idea that everything should be designed to be "reusable code".  That's insanity at best and project-killing ideology at worst.

A lot of what I see touted as "code reuse" is tightly coupled with some ill-informed manager or newbie programmer's idea of OOP.  I'm reminded of the days when you would see these giant monolithic functions chock full of global variables thrown into a "class" file in VB6 and called "objects".  As Forbes points out, this is happening in the name of being "best-practice" compliant without really understanding the best practice.  I see far too many people whose idea of reusable code (and objects for that matter) is that it is in another file, between the magic curly braces that come after the word "class".

When I design a system, and there's more than a few on the list, I tend to drop the areas of code into a few buckets.  You have standard UI and Data code in two buckets, domain code or "business logic" in another, and then "utility" code.  If you are architecting your project properly (yeah, I know that's subjective, bear with me) you have 2 primary targets for writing reusable code.  Data code and Utility code. 

UI code is largely UI-dependent, meaning you don't tend to reuse it for another project with a different user interface.  Putting aside the obvious exceptions like common control extensions, you aren't going to be able to reuse much of that UI code from that desktop-based healthcare app in your next project...which might be a web-based financial app.  This is the point of things like MVC and MVP right?  To make the UI completely agnostic of the domain logic (and subsequently valueless to future projects).  Same goes with the domain code.  What UI code you could generalize enough to be designed for reuse is unlikely to be worth the time and, let's face it, YAGNI applies here 99% of the time.

Similarly that domain code is going to be pretty project-specific.  Even if you were going to do similar projects in the same business domain for the foreseeable future, you're only going to be able to generalize a small portion of that code base to allow for future reuse because it's all tied to the requirements of this project.  This is even more true if you're running Agile because you're designing that domain logic at the user story level pretty much.

So that leaves us with data code and utility code.  Not coincidentally, these are the same areas you are likely to plug in an open source or purchased library to save you writing some code.  These are the right targets for taking the time required to write generalized reusable code.  Such as a library to make Word interop easy.  Here we have a requirement (generating word documents from data) that exists in 3 applications currently in place at my company, and I've had to do this code enough times in the past to assume I'll have to do it in the future, so I encapsulated it into a nice self-contained library that can be plugged in anywhere.  There's your smart reuse.  There's code that is an asset.  The next project that needs to do this type of word interop will be able to with virtually zero development time. 

The virtually zero development time part is the key to this whole reusable code issue.  If you think you are writing reusable code, and then dropping it into another project, and finding yourself spending more than say...30 seconds...refactoring or otherwise altering it to suit the needs of the new project, you aren't building reusable code, you're building a fancy snippet library.  At this point, you might as well just copy and paste the parts you need because you haven't achieved your goal.  Your "reusable" code should be reusable in the sense that the framework BCL is reusable, or that component you bought is reusable.  Plug it in, call some methods, set some properties, GO!  If that's not the case, then one of two things has happened:  you designed it poorly, or it wasn't meant to be reused in the first place.  I'm going to go out on a limb and say regardless of your architecture skills, a good bulk of the code people try to make reusable falls into the latter category.  It just wasn't meant to be.

 

Tags: