22

From my experience of working on several Java based projects, I've seen tons of codes which we call 'dirty'. The unconventional class/method/field naming, wrong way of handling of exceptions, unnecessarily heavy loops and recursion etc. But the code gives the intended results.

Though I hate to see dirty code, it's time taking to clean them up and eventually comes the question of "is it worth? it's giving the desired results so what's the point of cleaning?"

In team projects, should there be someone specifically to refactor and check for clean code? Or are there situations where the 'dirty' codes fail to give intended results or make the customers unhappy?

What I mean by WHY is not the technical reasons, I'm asking about the motive.** We all are familiar with why we should write clean code in technical point of view. But, imagine in college if I write bad code, I get bad marks. So in your industrial environment what motivates you and your team to write clean code? And what de-motivates you and team from writing bad code?

It's so easy to write a method in a class to get the information you need without looking around and checking if there's a similar method! Result? 5000 + lines of code with few methods doing almost similar tasks.

3
  • 9
    Is it worth the time to clean up the room when your stuff is all over the place?
    – BoltClock
    Commented Feb 22, 2011 at 8:34
  • 16
    @BoltClock - That one has been troubling me also for the past 30 years ;)
    – Rook
    Commented Feb 22, 2011 at 9:28
  • 2
    cos dijkstra's ghost is looking over your shoulder ;)
    – jk.
    Commented Feb 22, 2011 at 18:39

18 Answers 18

21

It's worth it, and it should be done by the whole team. "When it stinks, change it" works for babies & code (thanks, Kent Beck).

Some have said that for a little, short-term project, it's not worth doing. I don't agree. In the first place, we rarely know just how short-term a project is going to be, but in the second place - when it stinks, change it. If it stinks, it's either because you wrote it stinky in the first place - and your team should work on its general coding skills, and refactoring is good training for that - or (more frequently) it has been sloppily patched and repurposed over time. In that case - obviously it's not a very short-term project. If you had the time to stink it up, take the time to change it.

Refactoring - keeping your code from stinking - isn't the responsibility of one designated person on your team, and it isn't the responsibility of the person who made it stink. It's your responsibility and the responsibility of everyone on your team. When it stinks, change it.

6
  • I really like you concept of "When it stinks, change it". But from my experience, there's always a push for debug/feature-add than cleaning. I asked this question mainly to know what efforts other companies/teams take to keep the motive of writing clean code. Some projects I work on, it's too stinky and too late to change it. :-) Commented Feb 23, 2011 at 1:37
  • 2
    Thanks, @Shamal, but it's not my concept - it comes from Kent Beck's grandma, as quoted in Martin Fowler's Refactoring. Sorry if I left a contrary impression. Commented Feb 23, 2011 at 1:54
  • I believe this concept addresses what I wanted to know. From both business & development perspective. Commented Feb 25, 2011 at 2:38
  • 4
    You need a definition of "stinks" though. Many programmers will happily spend thousands of hours gold-plating code that would have worked fine and never ended up needing to change, or worse, ended up being deleted because customer requirements changed. Happens a lot.
    – MGOwen
    Commented Jun 21, 2013 at 2:03
  • @ShamalKarunarathne: It is almost never too late to change something. It's just that it gets more and more difficult the longer you wait.
    – sleske
    Commented Jun 21, 2013 at 9:35
15

The question is similar to why we should eat clean food. Simple points you can grep the net on:

  1. Maintainability
  2. Readability
  3. Easy to extend later on.
  4. Shows the character of the developer :)

But the "is it worth" question is little tricky. While deciding on this, you should consider:

  1. How long in future this project might run
  2. How mmore new features are expected to be added in long run.
  3. Risk factor; If its in prod, how risky is it to change (scary)
  4. Do you have enough resources to "waste"(?) on it.
5
  • 1
    That forth point is really important, since a small team can't venture into rewriting code, unless there is nothing else to do (and most probably there is)
    – Coyote21
    Commented Feb 22, 2011 at 14:43
  • 3
    I actually thing it comes down to the pain when talking about the 4th is it worth it. If your entire team is unwilling to work on a section of code or only one person is "qualified" to work on it. It's time to rewrite it. Life will be better if you get the cleaned up.
    – Erin
    Commented Feb 22, 2011 at 14:51
  • 4
    I don't think the question is similar to eat clean food. If I eat dirty food, I get diarrhea (I get the pain). But If I write dirty code, someday later someone else will get the pain. :-) Commented Feb 23, 2011 at 1:22
  • @Shamal, I was thinking more in terms of Cholera, its could affect you and me and everyone who read this post ;) Commented Apr 5, 2011 at 15:58
  • 1
    I disagree with the 4th point. Cleaning up code is not some "extra" that you can skip if you have too few people. Some cleanup is essential, and should be prioritized above new features.
    – sleske
    Commented Jun 21, 2013 at 9:40
13

I tell my students that this is the order I expect that code be written about (what I care about most to least):

  1. Documentation - if I don't know what it is supposed to do how will I know if it is doing it properly or not?
  2. Formatting and conventions - if I cannot read it how will I know what it is attempting to do? How will I be able to modify it if I need to and it is a mess?
  3. Correct - no point in having a program that produces the wrong result
  4. Fast (a distant fourth) - not much to say here

Simply put, code is written far less than it is read. Not following conventions (style) and writing quick and dirty code makes it much harder to read. SInce reading is the primary activity it saves significant time overall if the code is clear.

11
  • 11
    You don't teach your students to write tests?
    – Htbaa
    Commented Feb 22, 2011 at 9:06
  • 24
    Code has to primarily be correct - everything else is secondary. Perfectly documented and formatted code is perfectly useless if it doesn't do what its meant to.
    – Ben Hughes
    Commented Feb 22, 2011 at 12:12
  • 5
    @Ben Hughes: Yes that's the ideal, but as we live in the real world I would choose code to be maintainable rather than correct (assuming I can't have both). Correct - but write only code - is no good to me if I've to fix or otherwise change it. I'll just end up writing the damn thing again. Commented Feb 22, 2011 at 15:33
  • 3
    I’ve seen this happen. I took a job with a “very successful” company who sold a web based. C++ code base, 5 or 6 years old. It was first developed as a thesis project by one of the company owners, who was my technical lead in the company. It started life as a GUI app on the MAC, then became browser based, was then ported to Unix, then to windows. No code was thrown away, #ifdef’s everywhere (for platforms and for customers), no unit tests, and devs couldn’t run all parts of the code base. It took days to make the most minor changes. I lasted 4 months (cont) Commented Feb 23, 2011 at 7:58
  • 9
    ... less than a year later the company folded under the weight of multiple lawsuits, their "success" was an illusion. They did not have one satisfied customer. The bottom line is, code no one can work with (or only one person can work with) is of no use to anyone. You seem to think I advocate "shipping broken code", I'm not (because that's just dumb). However, if I have to hire one of 2 devs, one of who churns out working code, that only they can work on, and one that turns out well structured "pretty" code that nearly works, I'll take the second one, the first guy isn't welcome here. Commented Feb 23, 2011 at 8:09
13

You're actually asking several different questions here.

Why write clean, refactored code?

One should do this because it makes maintenance and verification of your results easier. If no one but you can understand how your code works without a massive time sink, then they can only take your word for it that it's actually doing what it should. If you're unavailable when a critical problem is found, then it's as likely to be made worse as fixed.

Aiming for maintainability has been one of the commandments of software engineering since the dawn of time.

it's giving the desired results so what's the point of cleaning?

Depending on the expected timeframe of your project, it may not be. If your project is only going to last six months on a very definite timeframe, you can probably get away with leaving things as a mess. Customers generally don't care what's going on under the hood, they just want it to beep and tweet at the right times.

However, if your on something longer term, then maintainability is going to become a large factor. On average, you can expect and should plan to lose key staff if you're on a timeframe of more than six months.

In team projects, should there be someone specifically to refactor and check for clean code?

No, I would say not. The person "refactoring" the code should be the person who originally wrote it, or there's going to be misunderstandings. Much like the rules of database normalisation, if you spend a little time thinking and refactor as you go (opportunities for doing so should be obvious as you work on the code), then there shouldn't be a lot of untidy code lying around for you.

Certainly, don't leave it until after the code is feature complete, as then from the developers perspective their job is done, the feature has been made and they can close the ticket.

2
  • Agree 100% on all points! Commented Feb 26, 2011 at 21:02
  • +1 for "Certainly, don't leave it until after the code is feature complete, as then from the developers perspective their job is done, the feature has been made and they can close the ticket.". I would add that with time it gets even worse: the code is dirty but the team is familiar with it because they have been reviewing, extending and bug-fixing it. If you eventually decide to clean it up, it will be better written but will look less familiar for a while: this confusion can cause a temporary decrease of productivity. So: either very soon, or never.
    – Giorgio
    Commented Jun 20, 2013 at 21:48
8

Reducing internal quality slows you down.

If you reduce internal quality, producing desired results in the future will take longer and longer, with increasing risk.

If you carefully choose the right thing first - getting the most value first - then in my opinion, it's almost always worth it to make the thing right.

Also, take a look at Martin Fowler's excellent article: http://martinfowler.com/bliki/TradableQualityHypothesis.html

(Paraphrased quote: As soon as internal quality is framed as tradable, the developers, management and their customers have already lost.)

1
  • Wow, I like the article. And thanks for the ideas. Commented Feb 23, 2011 at 7:10
6

Dirty code hurts when you have to work with it. Working with it means fixing a bug that relates to the code or adding a feature around the dirty code. I don't think there is much value in going in and refactoring code arbitrarily; code should be refactored when you are touching it to fix a bug or add a feature. In general, I love the Clean Code book idea of relating to what the scouts say: Leave the camp cleaner than how you found it!

If this is followed your overall cleanliness (and quality) will improve overtime, while the risks of (for no reason other than cleanliness) changing code that is currently working will be minimized.

I don't think that after-the-fact reviews to make sure code is clean will work, and having a person that exclusively refactors won't work either. As a developer I think we should all eat our own food. So we should be in charge to make good food.

If someone keeps bringing rotten apples to the potluck, the rest are bound to make him/her change or make him/her go...nobody wants to eat rotten apples. We should all be bringing awesome food to the pot luck.

3

I think that it very depends on your project. If it is a fixed price project done by one person during 1 week write code as you want.

But if the team is larger and the project development takes more time it will definitely require some sort of re-factoring and cooperation between team members during the development. These are the points where you will start to enjoy better design and cleaner code.

3

My opinion:

It depends! - If the code is meant as a one time development in the style of fire once and forget... then I'd say... no, it isn't worth to refactor it. - If the code is meant to be long living and be reused, then I'd say: write unit tests and refactor step by step, as soon as you have to modify/enhance code in or that uses those dirty part of codes.

You have to find the right balance between risk of breaking working code and benefits in term of maintenance and performance costs caused by the clean-up.

1
  • 1
    @ Danilo -- in theory I'd say you are right but in practice I have found virtually no "fire once and forget" code. I always tell people working with me "there is no such thing as test code": better to write it neatly / maintainably from day one IMHO (but it is just an opinion!)
    – AAT
    Commented Feb 22, 2011 at 13:34
3

Your code will be used by other developers. Even more, you will be using your code in future. Thus, if you will invest some time in writing clean code in the beginning, others (and you) will save much more time in future during debugging or modifying your code.

2
  • 1
    Also "used" will probably include "read" and "modified". Modifying ugly code is not fun and it becomes outright painful when it's ugly code written by someone else (or by yourself several months/years ago, which is essentially the same). Commented Feb 22, 2011 at 8:53
  • +1 for identifying that the time required for others to understand your code is also a cost.
    – Sparky
    Commented Feb 22, 2011 at 14:27
3

I would put the good points raised by other answers in a slightly different way.

it's giving the desired results so what's the point of cleaning?

In other words "if it ain't broke, don't fix it". Which sounds correct, however it fails to take into account that code can be broken in several different ways - it can be:

  • functionally broken (the most obvious): it does not do what it is supposed to do,
  • incomprehensible: it is hard to read and understand, so it is not even clear what it is supposed to do,
  • untestable: it is hard or impossible to unit test it,
  • unmaintainable: it is hard to maintain and extend it - this is usually a close consequence of it being hard to read and/or unit test.

Any of these can hinder or even kill a project in the long term.

3

Everyone's already answered the question well. But the decision point for me on whether it's worth it or not largely depends on whether the app is going to change more over time. As everyone else has said, if it works and doesn't need to change, move on to higher priority things. But if you're going to have to keep changing it, then not refactoring for cleanliness and efficiency will cause problems down the road.

I worked on a really rotten app once that when originally written was small and fairly easy to deal with. As years of additional features and hacks and sloppy fixes kept adding up, the analyst on the team commented once, "What I find most difficult about the app now is how long it takes to change it." Even doing impact analysis for a new change could be costly.

However, the answer to your question, particularly when considering the motivation part, will be different depending on who you ask. For an internal IT app, where the cost is paid for by free overtime hours, developers would want to improve the internals while few managers would be interested in changing them. For a shop where velocity of evolution is important in time to market, quality could provide a strategic advantage, if you had management that believed the speed of changing a well-built app exceeded the speed of hacking a new feature in. And sadly, even in some true software shops, I get the sense that a lot of managers decide that hacks are faster. Maybe they are, but again, the ongoing pain is usually felt by the developers and not others in the organization.

2

From business point of view I don't have big objections for one-off dirty code if it works. There is a lot of crappy software making money for business.

But good habits and programming skills are not coming from nowhere, they have to be developed. Writing good code is a great exercise for writing good code. More good code developer writes, the easier it becomes to do. It is quite natural to write good code, it is not harder or slower than writing dirty code, this is just an experience + good habits and this experience and habits can't be obtained by writing dirty code or just by reading books. So don't write dirty code and don't let your team do it and you'll be a better developer with better team in some time. Business tasks and deadlines go, skills stay.

2
  • Hi Mike, I actually like your point of view. But it's easy to write dirty code than good code. It's easy to write a quick method in a class to get what you want without looking if there's actually another method to do so? am I right? Commented Feb 23, 2011 at 1:08
  • In my opinion if classes are clean and small and have well-defined purpose not much efforts are needed to spot the repeated code (it may be harder not to spot it). Experienced developer should also know standard library and tools and not re-implement them. If classes are messy and nobody understands them then it is indeed easier to continue use bad practices. Looks like Broken windows theory: the only escape here is to consistently practice good code, develop skills and then it will be easy and natural. Commented Feb 23, 2011 at 19:51
1

Rewriting code to make it "clean" or "neat" shouldn't be undertaken lightly. Unless you have time to really get to know the code first you're liable to make mistakes that can be very hard to catch yet make parts of a system that have worked reliably for years fail in mysterious ways.

I'm working on such a task myself, where things had got too far out of hand (God class anti-pattern, anyone, massive copy-paste programming, etc.). There I had the time, and still I only did a small part of what I'd really have liked to do because I'm not confident to do everything, the changes needed to really make it quality code would be too great and would effectively mean a rewrite which is way out of scope of this project (what I've done is mainly make the code a little easier to read so I could find places I needed to make changes intended for the project, and centralise those changes rather than sprinkle them all over the place). And even such a limited change (limited, as in reducing the existing 9500 line class to 8100 lines, a real refactoring would split it up into several dozen other classes and probably introduce a complete database access framework like iBatis) has risks attached to them in that it requires a complete retest of the entire application which might yield problems introduced by the change. I've only done it because a complete retest was already called for because of the impact of the very minor changes I ended up making to the functionality (rather than the technical implementation) of the system.

1

I see two main motives:

Maintainability

Because the person who will have to maintain the code may be a psychopath who knows where you live. Or worse, you may be the one maintaining it and by then, you will have forgotten everything about how it is structured internally.

Easier to debug

It helps having solid foundations to build upon when you need to add more features, that way it's faster to identify where bugs come from.

1

It is essentially a question of money.

The better the code, the easier (and cheaper) it is to maintain. Both for others but also for those who originally wrote it.

Unfortunately, this experience cannot be properly communicated without actually trying it, which means that there can be a very large codebase which needs a lot of work to get into a reasonable state, which means that it is no longer the cheapest to do it right because you may have to rebuild too much. That's the dead-end many experience.

If you need to explain this to non-technical people then compare it with a house. If the basic blue-prints are not sound, then you will need to do a lot of extra work and you still have an inferior house.

1

Consider the implications of the FizzBuzz examples in this article. The two versions, and their modifications, give the same respective outputs, but which would you want to maintain, especially in an environment with constantly changing requirements?

My advice: When under tight scheduling constraints, if the code ain't broke don't fix it. When schedules become looser and deadlines are no longer looming, take the time to fix the most problematic or least modular code, but always within the guidelines of the overall system architecture.

0

You start out on a project with initial set of requirements.As the project moves on the requirement keeps changing and there is a need to extend your code.

When we start to write the code we try to make it work to the requirements we have currently and the ones we guess which might show up.

If you dont refactor your code there is a high risk that it will not be easy to extend it or be readable by others.

More over refactoring the code shows how clear you are on what you did and gives you opportunity to correct potential bugs.

0

To me in practice this question translates to 'Why write smaller code?', because in practice smaller, more unit-able blocks of code invite the possibility of nicer and cleaner design. Manipulating theses smaller blocks becomes much easier than the large ones, and they are more inviting to be refactored as needed.

Now, my answer:

after mulling over some significantly decent legacy code base refactoring, it has been my experience, that large blocks of code (classes, functions, etc), invite more code. More code applied indiscriminately breaks up the things like responsibility principle, and other best practices.

So my answer as to why write smaller code?

  • it forces you to think about your code structure and layout more, while preventing mentality (and sometimes necessity) of "let's stuff more stuff into this code block". I say necessity, because when coming across a huge block, it may be necessary to make things work now, rather than take time to refactor, due to time pressures.

  • It is easier to do refactoring work on a set of smaller self-contained code pieces even if they are ugly than to work on breaking up huge entangled ugly methods.

  • it helps future programmers who will be working on your code base to figure out what you were doing. While not always true, smaller units of code that have their purpose and that are reasonably self-contained, will help you build a mental model faster than long ambiguous everything code spans.

  • it prevents future programmers from moments of what the [heck] was this code supposed to be doing? and why does this or that code piece doing these things in this particular and peculiar way?, as large code blocks tend to hide bad practices and various bugs and logic errors.

Not the answer you're looking for? Browse other questions tagged or ask your own question.