I've been a zone leader with DZone since 2008, and I'm crazy about community. Every day I get to work with the best that JavaScript, HTML5, Android and iOS has to offer, creating apps that truly make at difference, as principal front-end architect at Avego. James is a DZone Zone Leader and has posted 639 posts at DZone. You can read more from them at their website. View Full User Profile

Write Your Good Code First

05.27.2010
| 10919 views |
  • submit to reddit

Writing good code first is a pretty obvious statement, but I'm not sure if people do this. In fact, I think that we make excuses all the time so that we don't have to.

While catching up on Twitter recently, I checked what @UncleBob (Robert Martin, author of Clean Code) has been saying. Obviously he's a smart guy, as pragamatic as they get, and always has useful insightful things to say. Here's the tweet that caught my attention: 

I'm sure most developers would say that they write good code, always. Think about it? Do you? I know I've definitely compromised my quality standards in the past, deciding that it's better to "fix that later" rather than to get it right first time. The minute you do that, you've broken a window

While on this topic of writing good code first, you might wonder where refactoring fits (but I hope that you're not wondering!). Refactoring is inevitable, but what really gets me is when refactoring needs to be put down as a separate task in a project schedule. Looks like UncleBob would agree:

 

So why does it happen?  To me, seeing refactoring in the schedule is an admission that "you're not going to get it right first time, so we'll add in this extra time to fix it later". Surely if there is a concern that the time allocated to a task doesn't cover a complete, clean implementation, the task needs more time. Refactoring is a good thing, but you have to refactor as you go. Don't commit too much code littered with //TODO comments, do it now. 

Having refactor seen as a different task is the same as breaking down each feature into a list of tasks like design, unit test, code, refactor, test. Software developers should know what they need to do in order to produce quality software. The "task" is not just the coding part - it's everything around it. 

 

Comments

Fabrizio Giudici replied on Thu, 2010/05/27 - 3:37am

I agree, but with some remarks. The point is that "good code" isn't a meaningful thing if you don't put it in context. I mean, in the context of Uncle Bob it means code of excellent quality, in the context of normal people striving to improve while delivering and dealing with all the everyday's mess it means another thing. The "optimal" code isn't necessarily the fastest thing to do initially, since often they're learning how to write better code while working on a project.

My point is: strive to write first the better code that you can afford, but above all go TDD. If you have tests and initially suboptimal code, at least you're fulfilling your targets. Having tests, you can afford to refactor code continuously and you can improve it later. 

James Sugrue replied on Thu, 2010/05/27 - 3:50am

Exactly - at any stage in the process you should aim to do the very best you can. If you can't honestly say that "this is the best I can do", then it's probably not good enough.

 

Manuel Jordan replied on Thu, 2010/05/27 - 6:16am

I would consider too, documentation (like javadoc), I have seen many times good, ordered,concrete code without documentation, afterwards of a time, the storm comes when they need do some changes. Of course they cant recall in a 100% the functions of each parameter, what exactly does the methods, and who and why call the method, just my two cents.

Senthil Balakrishnan replied on Thu, 2010/05/27 - 7:20am

I completely agree with you!!!

Certain common sense doesn't come easy to developers :)

Similar thoughts of myne

Philopator Ptolemy replied on Thu, 2010/05/27 - 9:04am

I’m probably gonna draw some fire here, but I can’t say that I completely agree with this puritan and rigid approach.

From my experience there are cases when “getting it out there ASAP” is a matter of absolute necessity. Furthermore, by doing a first suboptimal implementation – you learn more about the domain, the problem and the solution. Then you can and should do the refactoring (that I never neglect). I’m not trying to negate existing methodologies or come up with a new one – i'm just trying to be practical and pragmatic.

I agree that tests are absolutely necessary for refactoring, but, again from the experience, some of the tests can be added after the initial implementation. I know it sounds like heresy in this TDD world but it did work well for us many times.

 

Avi Yehuda replied on Thu, 2010/05/27 - 9:42am

I agree with Philopator. Not only that, I can even tell a story from my own experience.

My previous job was at a small startup company in the mobile business.
We did everything by the book, right from the start. We designed a massive distributed system and we started developing.
As you wrote in this article, we didn't compromised, we were extremely thorough and we wrote excellent code.
The problem was, it took too much time, the financial crisis of 2008 caused our investors  to fold back, and by that, close down the company.
A year worth of quality code was thrown down the well.

Looking back I am certain we could get something done even in 2 months and get it out to the public, and when you have users there will be investors.
That was my lesson from that experience. In the real world, sometimes it is more important to be fast than to be good.

And if you are still not convinced, I would like to remind you the story of Twitter.
In case you don't know, Twitter was first written in the most terrible way. The performance, the framework, the technology were all terrible. When twitter just started, no body believed it would survive, since it keep collapsing and it had absolutely no business plan . But it had one advantage over its competitors - since it was first to do what it does it had a lot of users - that's the only reason it survived. After it was clear people are using Twitter it had no problem getting investors again and again (even with no business plan). After Twitter got invested it had no problem rebuilding the application from scratch and writing "good" code.
If Twitter would have been written from the start as it is written today, it would probably be out to the public at least a few months later, maybe even more than a year later. There is a good chance Twitter would not be where it is today, in this case.

James Sugrue replied on Thu, 2010/05/27 - 10:42am

I see where Avi and Philopator are coming from - you definitely don't want to overspecify. The thing is that good development principles can still apply to the "get it out there ASAP" approach. Once you have the right features specified, you know what you need to deliver, then your design and code should be as good as possible. For every story there is of projects that have done well without the puritan approach, I'm sure there's a few stories of failed projects who took the "hope for the best" approach.

 

Fabrizio Giudici replied on Thu, 2010/05/27 - 1:24pm

No problem with the heresy... :-) I myself don't go 100% TDD (sort of 70%, probably). I agree that the important thing is to have tests, even though they didn't come from TDD. It's a matter of grain of salts. I'd like to stress, in any case, that especially when you want to trade off some quality for speed, that is, speed is important for the reasons quoted by Avi, the risk is that tests-done-later fall under the reap of lack of time or money. In this way, the risk is that you go fast to the market, you get some ROI from the first deployments, and then the project dies young because it gets soon out of control. TDD has got the advantage that, being written first, tests won't suffer too much from the budget cuts.

In any case, we're all saying a very savvy thing: "pure" approaches exist mainly only at conferences; in the real world there are many forces driving you and you must find the proper mix.

Andrei Solntsev replied on Fri, 2010/05/28 - 9:16am in response to: Manuel Jordan

Hei Manuel, there is a problem with documentation: it often lies. I have seen many times documentation telling something other than the code really did. Fortunately, there is a better way to "document" your code, see more details in my blog.

Josh Marotti replied on Fri, 2010/05/28 - 9:24am

Lots of good comments, and I'm just going to push the message already given in most of them:

Extreme programming says to get the code to work, first.  Optimize later.

Yes, write good clean code, but don't make assumptions on where the choke points will be, or worse, overarchitect.  Write clean code, but don't go bananas on the architecture.  Your architecture should focus on your needs, not what you think is best.

Manuel Jordan replied on Fri, 2010/05/28 - 12:40pm in response to: Andrei Solntsev

Hello Andrei

Thats correct, the paper (in this case javadoc) can support anything, of course I mean about the right documentation, I going to read your link carefully this weekend, thanks for share it! =)

-Manuel

Alexander Ashitkin replied on Mon, 2010/05/31 - 2:01pm

one more guy who reads too much books and never trying to implement a project with limited budget. see at the world around you - best software is the working software. i don't know a customer and even more an investor who will listen a stories about the "excellent code" if doesnt see a progress and useful features. But i do know examples when our project survived because we showed very basic functionality with the horrible implementation and static html to demonstrate a progress to a customer.

Stephane Vaucher replied on Sun, 2010/06/06 - 4:10pm

And a bunch of guys who never had to maintain software.... Do you really believe that most software is written from scratch? Good code is more maintainable and cheaper on the long run. You might need to write bad code for a client demonstration, but it should be treated as throw away code. For example, it could serve as:

  • 1. The basis of functional requirements for a better written version;
  • 2. a placeholder that would be replaced better version (modularity would be good).
For someone who does TDD, good code should be, by definition, unit testable.

We need to remember that Uncle Bob does believe that a good craftsman will assess what quality is required for a task. If a craftsman is writing a prototype, the quality will not be as good as a the quality for a peripheral driver. Bad code can exist in a system, but it should be isolated.

Alexander Ashitkin replied on Mon, 2010/06/07 - 1:26am in response to: Stephane Vaucher

if you meant me - i did software maintenance and in very large companies (so called global companies). my previous post is based on my expirience and my expirience tell me (it's more relieble source for me then @UncleBob) - make a working software. But i don't propose to create a bad code. I propose to focus on customer expectations instead of imaginated "clean code".

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.