Clean Code Versus Great Code

24 commentsWritten on July 21st, 2011 by
Categories: Code Quality, Opinions

I've had some interesting discussions with other developers about writing code recently. I often have the impression that some developers put too much emphasis on clean code. Don't get me wrong, i strive for clean code as well, and have written about its importance quite a lot in the past couple of years. But when i'm coding, clean code is my secondary goal and it could never take the place of my primary goal: making it work. And preferably, i want to make it work great.

A lot of people love to talk the talk when it comes to writing clean code. They'll stress their dedication to it, in some cases even wearing Uncle Bob's green band while coding so they'll never lose sight of what's incredibly important to them: writing clean code. Unfortunately, i've noticed on numerous occasions that many of these people don't always put as much emphasis on what the code is doing compared to how it looks. Sometimes they don't really bother to learn what their ORM is doing behind the scenes. Or they'll prefer to use something like Automapper to map entities to DTO's even though it is woefully inefficient compared to simply retrieving projected data. They don't always think about the cost of multiple remote calls or sending way too much data over the wire. And when they're not perfecting the art of writing bowling games over and over again, they just might hit the database in loop.

Clean code is not necessarily great code, nor is great code necessarily clean code. To me, great code is code that works great, performs great, is easy to understand and easy to change. In that order. I know all too well how important it is to easily understand code when you first read it, and to be able to easily and safely make changes to it. But no matter how easy it is to read or change, if it's not doing what it should be doing (including covering all the corner cases) or if it's taking more than its fair share of time to do it, it's not good code. Sure, it might be clean, but it's not great, is it?

That doesn't mean that you should indulge in premature optimization. Unless you have Neo-like skills in this coding Matrix, you're unlikely to be right in even a quarter of all scenarios that you want to optimize prematurely. There are however a few guidelines which will help you avoid most common performance problems. Most other situations are better left ignored until proven by a profiler to be a bottleneck. But you should at least think about what the code is actually doing and whether or not any downsides to that are worth the cleanliness. Don't hesitate to go with the slightly less clean looking code if that code makes more sense from a correctness and performance point of view.

By all means, strive to write clean code. But think twice before you sacrifice its ability to be great.

  • Philip

    I agree that you should *never* sacrifice correctness for cleanliness.  And I have many times seen clean but incorrect code, and clean but bad code and those people should writing it should be worried about correct and good rather than clean.   But if you start with clean and good code…

    Clean code should be clean enough that it is easy to change from good to great whenever you wish to.  You can keep it good or great when things change (like requirements or libraries, etc).  You can later add great things to it, or optimize it.

    Great code that is not clean is much harder to change when things change.  Who cares if it was great when it was written, if it is too hard to change? 

    Honestly, in any environment where code must later be changed or otherwise maintained, Great Code would by definition have to be clean – because  ”change” is one of the things the code is required to do, and it can be just as important as things like performance.

  • http://twitter.com/vkornov Victor Kornov

    Clean Code is required yet not sufficient for having Great Code. Unless you really wanted to talk about “good enough” code that “gets the shit done” and that nobody really cares about how your code looks like as long as customers are satisfied.

    • Jon Wingfield

      I think you have it backwards.  His definition of “Great Code” is code that accomplishes a goal, within an SLA.  Great code is necessary but not sufficient for Clean Code.  Code does not have to be clean to accomplish a goal, but it does have to be great.

      Granted, the words aren’t very scientific…

      • http://twitter.com/vkornov Victor Kornov

        Well, Clean code and Great Code are 2 different qualities of code that you really want to both be present. But given a choice, choose Great versus Clean.

        P.S. Sounds like Cap Obvious, as well as the original post too.

  • anonymous coward

    While I can’t disagree with anything you are saying, I can only see this post as a force for badness…since anyone writing “great” code already agrees, and anyone writing “cut and paste get ‘er done” crap that is non-performant and buggy as well as horribly designed and structured just found some misguided validation.

    • http://davybrion.com Davy Brion

      in my experience, people who write “cut-and-paste get ‘er done” crap don’t read blog posts… they just skim them for code and don’t bother actually reading what is said

      so i think we’re safe here :)

  • http://thezendev.com Dan Martin

    Off-topic, but I had to laugh at your link to the post about hitting the database in a loop. I’m fixing the performance for some code right now where some ass decided it would be a good idea to hit the database in the loop approximately a million times.

  • http://twitter.com/msuarz mike suarez

    I’ve seen way more optimizers than clean coders out there … u might b barking at your own tree 

  • http://www.facebook.com/profile.php?id=669328712 Chuck Bryan

    Davy – I think what happens (speaking from experience) is that we read Martin’s book and have an epiphany about what code could look like. However, we forget that Martin often states throughout the book that code does not start clean. It can’t. That’s like putting together a View and expecting to have it all styled up before you get it functional.

    For me, clean code is part of the refactoring process – once you have it working, then you make it pleasant for others to come in behind you. I wish ReSharper had a Clean Code refactoring method.

  • Pingback: The Morning Brew - Chris Alcock » The Morning Brew #900

  • http://twitter.com/markrendle Mark Rendle

    I like to think of myself as a “duct-tape programmer”, but at the same time, having spent the last few years trying to follow the practices espoused by Bob Martin and others, I am now in the habit of writing reasonably clean code off the bat. In the years it took to get into that habit, I may have written some code which was clean but not great; however, once profiling tools and user feedback highlighted problems, I believe it was much easier to go back and tweak the clean code than it would have been to dive in and clean the “great” code.

    I’m not going to say any more here or write a post just yet, because I’m working on something in this vein for Øredev…

  • Andre

    Great post, but you chose to create another name for it “Great
    code” which is also open to mis-interpretation as apposed to clean code which
    already has tons of definitions already proven.

     

    A clean coded system will be one where methods and classes
    are small, well named, have single responsibilities and are therefore easy to
    extend modify and understand. Clean code is also about Dependency injection and
    unit tests (easy to change)

     

    A clean coded system is way easier to Expose, modify and
    verify (through unit tests) these performance issues.

     

    You used the example of not understanding the ORM in the
    background.

     

    Unless you’re doing something stupid, in most cases we build
    the system around abstractions. I am not really supposed to know how everything
    works behind the scenes it is just therefore the point of using abstractions
    and libraries. If im having issues with performance and I used clean modular
    code using abstractions I can merely replace the underlying library or functions
    with a version that performs better.

    • http://davybrion.com Davy Brion

      “If im having issues with performance and I used clean modular code using abstractions I can merely replace the underlying library or functions with a version that performs better.”

      that’s exactly the problem… it’s a fallacy.  As soon as you have out-of-process calls (database calls, webservice calls, …) you will not be able to simply change the underlying library to get better performance.  Any kind of performance gain that can be gotten from a change of library will only be a fraction of the gains you could get if you were using it wisely in the first place.

  • Ian

    Good post; and I agree.  Whilst clean code is nice to work with, it seems to be a bit of an obsession with some developers and sometimes has a negative impact on the immediate problem.  Clean code is useful on occasion, but if the code does what it is supposed to do; and efficient enough, then you may never need to look at it again.  

    Sometimes we need to ask ourselves, does my manager / client care what the code looks like; the answer (99% of the time) will be ‘no’.

    • Fan of Uncle Bob

      Anything is open to mis-interpretation some developers are
      obsessed with a misunderstood concept about clean code, same as misunderstandings
      about agile methodologies or what is referred to here as Great code. It is no
      different.

       

      Does my manager or client care what the code looks like? It
      doesn’t matter, clean code is not about what it LOOKS like but testable code means
      easy to write unit tests means client gets working software that is either bug
      free or 98% bug free. Clean code is easy to extend and modify by design which
      means client gets changes and new features faster.

       

      I like the analogy of misguided validation as I’ve worked on
      a system before where a table of 200 columns where each field was indexed by a
      numerical index ie the username field was in fields[179] for instance, the
      developers/architects of the system did this on purpose because it performs
      better than fieldbyname(“UserName”) which is a string comparison loop on each
      item. Had they understood extensibility and Clean code they would have known to
      create an abstraction or stick with the fieldbyname but rather implement a
      dictionary lookup which would be as fast but a million times more maintainable.
      Also the problem seemed bigger 5 years ago and today wed rather have the ease
      of maintenance then the 5ms we saved. Of course again everything DEPENDS. You might
      have a real time trading system where every microsecond counts, in such a case
      you might even want to write some assembler, but the point is to create that abstraction
      and that API that makes it clear what the intent is what the code does and how
      to change it.

      • http://davybrion.com Davy Brion

        I think your example with the indexed fields fits perfectly in my warning against premature optimisation. I also never advocate writing code like that.

  • Peter Hendriks

    Code has two audiences: the machine and the programmers. You really can’t ignore or prioritize one over the other in the long run. It not just about making “it work”, code also _needs_ to be understood and changed next week.
    I think I understand the sentiment you try to convey, but prioritizing correctness or performance over cleanliness imho only inverts the fallacy you try to warn about. Perfect is the enemy of good enough. Great code must be both clean and correct enough for today, and should become better tomorrow as its creators have learned more. And yes, this is vague and demands responsibility, knowledge and discipline from the programmers. That’s why they pay us so well, right?

  • Anonymous

    seems what uncle Bob calls clean code is your definition of great :>

  • Anonymous

    Clean code and great code are not mutually exclusive, although I often feel that there’s more emphasis placed on the former by business. As hardware as improved so quickly in the last decade, there’s less pressure on developers to write great code. I find this disappointing as my favourite aspect of development was creating tight algorithms.

  • Mariusz

    Good remark about “premature optimization”. Avoiding premature optimization doesn’t mean that you can for instance call a remote method returning the same value in a loop instead of retrieving it once before a loop and store value in local variable. Why “first make it work than make it fast” must mean “first make it work badly and then bring it back to normal”?

  • http://twitter.com/sschuermann Sebastian Schürmann

    Clean Code Development is a little endangered to become Cargo Cultish. 
    I loved the book, I hate the dogmatic discussions around it

  • Mituzhishi

    Clean code and working code do not conflict with each other. We could achieve them both.

  • Dennis
  • Leizisdu

    Thank you for your talking:D