Quality programming

Over the last few days I have had some discussion with other developers about code quality.  While to some degree those discusses could become a bit heated, I wanted to take a little bit to document how I feel about my personal experience with code.

1.) Quality code starts with effective communication

It’s easy to fall into a trap where you write a piece of code and -think- that it’s very straight forward and easy to understand, yet no one else can read it.  The question you should be always asking yourself is “How much of what I know about this code is because I wrote it, and how much do I know about this code is because it’s telling me about it?”

The truth is that code is always telling a story.  Is it being told because of you or is it being told in spite of you?  If we take the latter approach to writing code, then the language we use (or don’t) has a far more significant impact.  To that end, we should take proper advantage of the set upon conventions provided for us.

For instance, in the English language we have tools such as grammar, sentence structure, paragraph structure and even formal frameworks for organizing thoughts and statements.  In programming, those tools equate to code formating, naming conventions, comments, and pattern usage.  The extent in which you implement these things has to be appropriate to what you are trying to accomplish.  Not every piece of code you write is going to be a thesis, nor is every piece of code you write going to be a quick thought scribbled on a napkin.

I, personally, usually end up writing code pieces twice.  The first time I run code something like a rough draft.  I try to stub out all of my thoughts on how it’s supposed to work so that way when I go back to it and try to make it work it’s easier to mine the good ideas from the bad.  Even then, I sometimes refactor the end jewels into yet another final draft copy of what I do for the sake of readability.

2.) Quality code is appropriately flexible

The world changes fast.  Your bosses are going to change their minds.  The company is going to move in a new direction.  Knowing these things as being a basic truth, can your code keep up with them?

Writing code doesn’t have to be an all or nothing proposition.  Often times I find that programmers bind themselves to a set of requirements, and by doing so they create a situation where the code they write quickly grows out of control or at best is useless outside of the scope it was originally built.  This is rather apparent when code doesn’t take advantage of interfaces, or not abstracting code into proper layers of encapsulation.

In more concrete terms, all code is written against a basic set of assumptions.  These assumptions are generally very limited and likely also to not hold true for very long. In short, all code is uninformed.  However, not all code has to be ignorant.  Ignorance is not an excuse anyways.  Instead of stacking the deck against yourself and coding yourself into corner.  Set yourself up to succeed by really taking advantage of rich concepts like polymorphism (ad-hoc and parametric), data provider models, development patterns, interfaces and other abstraction models.  Be proactively lazy.  Do the work up front, and save yourself (and others) the frustration later.  You will thank yourself and so will others.   (As an aside, it may behoove you to look outside of OOP concepts for answers on flexibility.  Functional programing has RICH tools for helping create appropriate abstractions.)

So, all that said.. how do you know if your code is flexible?  We need to look at this in terms of the overall development process.  Search for evidence of your own code’s brittleness in your existing pain points at work.  How much of your code can be released w/o others going with it?  When a requirement changes, how much code also has to change with it?  What would happen if your code needed to be implemented by a different client?  What would happen if you needed to marge another data source into your code?  What if your database would change?

In short, don’t always think in terms of what is asked.  Try to think about things in terms of what is possible.

3.) Quality code does what it’s been asked to do

An obvious fact of quality code is that it does what you have been asked to make it do.  However, being able to achieve a goal is just the beginning of that statement.  This should broadly be discussed as assurance.  First you need assurance that your goals are achieved and second you need assurance that is ALL it does.

To speak to the latter first, my personal bias is that less is more.  I prefer not to use two words where one will do.  In programming terms, this is relevant here because often I find functions that try to be everything to everyone.  While I know I just mentioned code should be flexible, trying to be useful in all scenarios usually makes something useless for most of them.  Instead, I try to achieve the aforementioned flexibility by thinking in terms of composition and in small bitty contracts.  Your function should only do what it’s asked.  This is a complex issue, but you aren’t alone in trying to solve it.  I have found the *nixes to be a very useful model for understanding this better.  Small powerful tools make up a very powerful framework for greater tasks.

The other part of assurance usually takes place as unit tests.  Some places also achieve assurance through strong regression testing via the QA department.  In most places however, this doesn’t really exist at all.  My experience is that most places program by coincidence.  The fact that the end product appears to do what is asked is usually just a convention of luck.  This is generally not due to malice, however I do believe this is due to laziness.  Programmers have a tendency to write code so all it does is work within the bounds of very narrow criteria.  Instead of thinking about the reality of the scope, the software is written to just achieve a task only under the given requirements.

I would love to write more about this subject, but there are some very rich places out there to get support.  I think that Test Driven Development (TDD) can be a very use full tool to work with, but even more specifically I am a fan of the pragmatic press.   In the book “Pragmatic Unit testing in C#”, there is a discussion about what a unit test is, and what a unit test isn’t.  Most unit tests I have seen are really integration tests, meaning that they test a flow, but not to ensure quality.  The BICEP unit testing principles (Boundaries, Inversions, Correctness, Exceptions, and Performance) make lots of sense.  Read more about them in the aforementioned book.

This is just a beginning on what I believe quality is.  I don’t believe that this is an all encompassing theory, nor was I trying to make it so.  As a final thought, don’t mistakenly believe that quality code is only written by senior developers.  I worked with a gentleman a while back who is junior in his experience and skill set, but writes more professional code than most developers I have ever worked with.  Take a page from him, start NOW for a different ending.  You can gain experience and technical skills far easier than you think.

Advertisements
Post a comment or leave a trackback: Trackback URL.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: