Clean Development Series: Part 2, Dirty Code (why we do it)

Lately I have been talking about clean application development, and how developers can do a better job of it.  Due to the strong focus on this I decided to write some content from my latest talks into a series of blog posts.  Enabling everyone to reap the benefits of the subject matter, and allow attendees of my talks to refresh the content covered at one of the events I spoke at.

In Part 1 of this series I discussed the causes and effects of dirty code, and how disastrous it can be for us and/or our employer.  I think it’s easy to see how the terrible effects caused by writing dirty code is not desirable.  Most of us try to avoid wasting time, introducing bugs, increasing technical debt, causing our companies to lose money, and looking for a new job because our employer went out of business.  So if we don’t like these things, why do we write dirty code in the first place?  It is our own fault after all, but it’s not something we consciously do…most of the time.  Let’s take a look at a sample scenario, and see how we sometimes get ourselves in this type of situation:

New Job and a Simple Request

We start a new job, of perhaps we are approached by our supervisor with a request.  We know how it works.  The boss mentions how wonderful it would be if the application was able to do some sort of functionality, and asks if it’s possible.  Of course in our haste to please and impress we say, “Of course”, and head off to our lair to perform our magic.  We sit down behind the keyboard and already have an excellent idea of how to build the new functionality our boss was asking for.  What do we do first?

The Preparation

Do we write unit tests?  No.  Do we document the requirements?  No.  Perhaps we at least write down some sort of decision making flow chart?  No.  So we at least have an idea of standards we will use and follow?  No.  Well, maybe we download a framework, or figure out what functions we already have rather than recreating the wheel?  No say.

Execution

What actually happens is pretty mystical.  Like a maestro ready to conduct an elegant symphony we go back to our desk, fire up our favorite IDE or editor capable of helping us create the best code imaginable by man.  These tools have built in auto complete, connectors to version control, able to link to ticket and bug tracking systems, debuggers, project file management, structure tree display, code inspectors, refactor modules, and even direct connections to hosting and command line tools.  We can now create true masterpieces of intellectual property.

But we don’t have any time for all of those bells and whistles today.  We are excited and in a hurry to prove that our boss made the right decision by hiring us.  So instead of using these awesome tools at our disposal we code the entire thing in very short order, and then spend a few minutes to do some functional testing and ensure it doesn’t blow up on us while we demo it.

Presentation

Barely able to contain ourselves we rush into our bosses office to announce we have completed the functionality he requested.  Our excitement is quickly contagious and our boss looks on wide-eyed as we demo our accomplishment.  He is a little surprised we were able to finish it so quickly, and thanks us for our hard work.

Then, faster than we can think of what we will have for lunch, our boss immediately thinks of some sort of enhancement to the item we just completed.  He quickly outlines how it could work and what it could bring the company.  In the excitement of the moment, and our newly found feelings of accomplishment, we tell our boss it’s a small task and we should be able to get it done pretty fast.

We head back to our desk feeling the afterglow of the moment, feeling like we saved the world as well as earned our keep at this new employer.  Once again we have a task to accomplish.

Second Iteration

True to form we perform exactly as well on this second task assigned to us.  In our haste to please we ignore best practices, testing, and standards as we quickly complete the new request.  Upon completion, the meeting and presentation go pretty much like the first, and ends with yet another task.

More of the Same

This cycle continues over and over again, and we continue to perform admirably.  Our boss seems to be a wealth of knowledge and ideas, and we continue to turn these ideas into application at an astounding rate.  However, with each iteration there are more bugs, more overlap between one functionality and the next, and more “gotcha” moments as we try to demo the newly created functionality.  We are starting to struggle with the code base a bit as our technical debt has been steadily increasing little by little.

Longer Time frames

Of course we are smart, and realize very fast that those little “gotcha” moments as we demo to our boss are taking a toll on his trust of our ability.  We quickly realize we need to test a little better before presenting the functionality.  This requires some time to complete so we start to pad our time estimates a bit to compensate.  But with each task this time frame grows longer and longer, and soon these time estimates become a week, a month, two months, a quarter, then six months.

Unstable

By now our code has become so unstable we fear it, and are tripping over quick decisions made months ago.  There are no unit tests, no standard functional tests, no documented regression tests.  Our code is just layer upon layer of classes and functions that are so tightly coupled we constantly trip over them.  A change in one place causes things to break in 4 other places.  We have not even sat down and set a coding standard, let alone done any documentation of the application.

It’s at this point that every time someone makes a request our first answer is “6 months”.  However, we know in our mind that there is no way we can get it done in that time frame.  But marketing needed some sort of answer and there is no way they would settle for a number larger than 6 months.

Danger

We’ve dug a hole of technical debt over time by not using best practices, and we are in a danger area.  Our once pleased boss is questioning every choice and estimate we make.  Perhaps he is forgiving a little because he realizes we have worked so hard up to now, and we have earned some “professional credit” to this point.  We realize that action needs to happen…and happen fast.

Time to Pay

As with all debt, whether it is financial or technical, we must eventually pay it off somehow.  With financial debt we either pay it off by making payment arrangements, or we go bankrupt.  Technical debt is similar.  With technical debt we can either refactor bit by painful bit (making payments), or we can do a full rewrite of the application (go bankrupt).  Of course we could also leave the company and therefore leave the mess for someone else to clean up, but lets assume we are responsible developers and feel obligated to do the right thing.

Summary

I am sure most of us have played a part in the story above, and can nod our heads in understanding.  Hopefully most of us have learned from the experience and no longer do it. (Yeah, right.)  Those who have not had the luxury of making these mistakes should take heed of the story and learn from these common mistakes.  The story above IS NOT how to do things.

IMPORTANT: Our employers hire us to be professionals.  By following the sequence above we set the standard ourselves, in a bad way.  Please do things the right way, and be the professional you were hired to be.

Throughout this series I will continue to outline ways to avoid making these mistakes, and how we can accomplish “Clean Development”.  I hope you found this breakdown helpful, and learned from it.

Clean Development Series: Part 1, Dirty Code (cause/effect)

Lately I have been talking about clean application development, and how developers can do a better job of it.  Due to the strong focus on this I decided to write some content from my latest talks into a series of blog posts.  Enabling everyone to reap the benefits of the subject matter, and allow attendees of my talks to refresh the content covered at one of the events I spoke at.

Whether we’re experienced developers or newcomers, we’ve all seen code that could/should have been done better.  Many times it’s even code we ourselves wrote and revisited later for one reason or another.  I, for one, have seen my share of code written by a “past me” and wondered what on earth I was thinking when I wrote that.  Of course there has also been times I was hired to fix another developers code, and it can be scary too.

The code is pretty dirty if this is your reaction!

Side effects of dirty code

  • Time waster – The more dirty code we have, the longer it takes us to code.  Have you ever noticed that most of our time coding is spent reading code in other parts of our application?  This means that if we spend extra time sifting through dirty code, it takes us longer to actually write new code.
  • Breeds more dirty code – Also, we tend to care less about our code if we know there is already dirty code in the application.  This causes us to write more dirty code, because who will notice in any way?
  • Causes bugs – It’s a fact that dirty code causes bugs. (See a future section “How to spot dirty code” for more clarity.)  When we lose track of what our application is doing, and have trouble spotting problems, it simply leads to more problems.
  • Excessive debugging – I often ask my audience if they are good at debugging, and usually end up with a strong showing of hands from developers who feel they are good at debugging.  But if they wrote clean code doesn’t it make sense that they would need less debugging experience, and therefore would NOT be good at it?
  • Procrastination – We all do it.  We dread working with dirty code so much that we avoid it.  We make excuses to tell our customers, and we find other “more important” things that need to be done first.  I have even witnessed developers actually hiding from customers and taking on other projects to avoid a really bad codebase.
  • Technical debt – This is the most dangerous effect of dirty code. Think of this as buying things on credit.  As you buy more and more the credit line grows and grows.  At some point a choice needs to be made.  Either you need to pay it off, or you go bankrupt.  With applications this means you either fix the dirty code, or go through the added expense of a rewrite.
  • Financial loss – If your application has even a little bit of technical debt it causes development to slow down more and more over time.  If development slows down it can lead to your competition developing new features and applications faster than you can.  This is especially true if your application becomes stagnant and others continue to build.  A customer base can be very fickle and will leave surprisingly fast.
  • Company killer – In today’s lightning fast market place it is not hard to see how the above events can quickly kill a company.  Remember when MySpace was big?  I am sure we can all think of others.

Causes of dirty code (the perfect storm)

  • Too easy – Although it is easier in the long run to write clean code, we have all fallen into temptation to write dirty code to get something done quickly.  It is very easy to be drawn in.
  • Short deadlines – Customers are often a developers worst enemy.  They are demanding, and salespeople have been known to over-promise on new functionality and short time-lines to meet that demand.  This places a development staff under tremendous pressure to meet those promises, and it is usually the code that suffers.
  • Laziness – Yes, unfortunately there are times when we all get lazy. (Some more than others.)  I won’t dwell here.
  • Lack of “how-to” – A brief look at code we’ve written in the past is a great way to see how far we have advanced.  As a consultant I often receive requests from customers to enhance applications I have built in the past, and I get plenty of opportunities to marvel at past coding methods I used when I didn’t know any better.  No matter how far I come, or how much I learn, this still holds true on a regular basis.
  • Coupling – Many will recognize the term “coupling” and realize we are talking about OOP.  This is a method of helping use stay DRY (don’t repeat yourself) and making code reusable.  So, why is it bad?  That question is far too large to cover in this post, so I will make a note to cover it more later, but tight coupling is bad and loose coupling is good.  Feel free to search on your own to see what I mean.
  • Impatient boss – It never fails, even if we still have plenty of time left on our project deadlines we still hear the dreaded “Is it done yet?” from business. It’s their job to ask, so don’t let it burn into you.  The faster they get it, the faster they can sell it.  But it leads to dirty code as developers strive to please.
  • Bored of same ol’ app – Most large applications take 6 months or longer to build, and this can lead to some long periods of working on the same module or functionality.  Eventually developers can tend to get bored, and will try to get things finished quickly for an opportunity to work on something new and exciting.
  • Intend to return for clean-up later – While in a rush to meet deadlines or to move on to more exciting tasks it is common for developers to complete things in a dirty manner with the intention of returning in the future to clean up and refactor.  Usually this never happens due to new projects and more deadlines, causing the old mess to be forgotten.

As you can see from this first post in the series, dirty code is dangerously easy to create and can carry disastrous outcomes.  I hope this post helps some to spot these pitfalls a bit easier, and make it easier to avoid them.  Please return for future installments as I attempt to highlight more areas to help us all perform clean development, and write better applications.