How good is good enough?
I've undertaken a couple of project reviews recently where I've been asked to assess whether the code is "good enough". All software systems have a real-world context and the project has to balance scope, budget and schedule. With this mind, what is "good enough"? Kevin has touched upon this before and I've talked about having just enough quality, but what does having "good enough" code actually mean?
Here are some of the questions that I try to answer.
- Is there a comprehensive set of automated unit tests, or evidence that the code has been unit tested (e.g. presence of boundary/null checks in the code)?
- Have good object oriented principles been adopted when putting together the design? For example, do classes have clear responsibilities?
- Have standard APIs and technologies been used? In other words, have any wheels been reinvented? If they have, is the alternative solution as good or better than the standard solution in this context?
- Does the codebase feel consistent, in terms of style and the approach to solving problems?
The last point raises some interesting questions. It's really easy to get carried away when doing code reviews and flag up a large number of points ranging from inconsistent code formatting and lack of comments through to using better APIs and the latest language features to solve problems. Given the real-world context in which the system exists, that piece of software needs to solve a business problem and points like these are fairly minor in nature1. However, an inconsistent codebase can highlight those instances where there is an overall lack of explicit technical leadership.
If you were to look at your own system, how would you decide whether the code was good enough?
1 Although it's arguable that points like these are minor in nature, I still think that it's important to ensure they are raised. Personally, I don't like to see things like this in the codebase for a system that I'm responsible for, but you need to present findings from activities like code reviews as appropriate. These minor points are important for the development team, but not so important if the key project stakeholder is asking you whether the code is good enough.
Re: How good is good enough?
You're a brave man mentioning comments, are you trying too start a holy war? :). I have pretty mixed feelings about comments, broadly speaking if your code needs comments to explain what is going on you probably have a larger underlying problem in that your code isn't as explicit as it should be. Comments are rarely kept upto date and often confuse the issue by stating what the code is intended to do (which I admit can be handy) rather than what the code actually does.
Or perhaps I've just spent too much of my life working on appalling code bases written by other people?
Neat code is an interesting one, although minor from a technical perspective I think it suggests something about the person/people who wrote the code.
If code is untidy it's fair to assume that a number of bad things could have made it that way
- Lack of a quality focus, it's not hard to write good code
- Time pressure, this always adversely affects code
- Developers who aren't that good
Re: How good is good enough?
I would argue that the most useful comments don't say what the code does, but rather why it does it. The what you can get from reading the code, but answering why a class exists in the first place, or why particular variables are modified in such a way, it often far less easy to determine.
I agree with David's points about untidy code being a symptom of bigger problems. The article itself I found a depressing read, as I'm currently working on a system which answers a resounding NO to all the questions you raise. Knowing what needs to be done is one thing, getting the business buy-in to change this sorry state of affairs, however, is often only possible when one of the painted-over cracks in the wall causes the house to fall down.Re: How good is good enough?
"Good enough" to keep in preference to throwing it away immediately and re-writing from scratch? Yes. (Joel was banging on about this argument back in 2000).
"Good enough" to blissfully hand over the ownership of the project to another team, claiming it's a self-documenting masterpiece? No. The increased maintenance cost likely to be incurred due to a "lack of explicit, consistent technical leadership" (pardon the paraphrasing), coupled with the potential issues highlighted by David in the comment above, would need to be accommodated for.
Perhaps all systems fall between these two extremes. Depending on why you're asking the question of "is it good enough" will veer your opinion towards one or the other. We can all whinge that the code is rubbish, but if the cost of the re-write is coming out of my own pocket, all of a sudden my opinion is likely to be less fatalistic.
Re: How good is good enough?
Re: How good is good enough?
A messed-up codebase can definitely be good enough. Several of the systems I've worked on have been in domains that require continual short-term change requests to be applied. The remit of the development team prevented continual refactoring.
Could it be done better? Of course. Could it be done quicker? Almost certainly. Could it be done cheaper? Not without suffering in other ways.
Re: How good is good enough?
I think you're right about "why" rather than "what". I tend to comment code rarely and only if I'm writing a complex algo that isn't obvious or where I've had to obfuscate the code for performance or other reasons. I'd put money on the fact that 90%+ of comments are "what" rather than "why" and therefore (IMO) pretty useless :(.
Over commenting or commenting for the sake of it actually makes code worse because it makes it harder to take in a whole routine/class/... on a single page. Enforced coding standards where each method/class needs a header are good examples of where this causes issues.
Perhaps this is self-fullfilling but in my experience teams that do code reviews are rarely the ones that need them.
Re: How good is good enough?
Re: How good is good enough?
Putting a "good enough" twist on your question, I'd try to determine how important their answers are to the system that you'll end up with as a result. Is one variant a subset of the others enabling you to go with the more complete approach? Do you need to know the answers now - can you start designing and building without all the answers? Can you work on several approaches?
In the absence of decent requirements you often have to provide your own for the sake of making progress : on time, on budget is a very strong requirement! You may also find that providing your own answers will get a much stronger response (often negative) from those who were supposed to provide them.
Depending on your methodology you may want to highlight the impact of the delay or forego getting answers and try to maintain momentum by getting a prototype in front of someone.
Re: How good is good enough?
Re: How good is good enough?
A good point - the developers, as the consumers of the codebase - are a good way of gauging code quality.
Perhaps I'm driven a bit too much by my recent experiences but I'm always wary of whether the developers would know good code if it jumped on them and whether the next iteration of the code is even going to use the same development team! Perhaps in such cases, it's the quality of everything else that's going to be important (such as the SAD).
Re: How good is good enough?
So, it is a waste of time thinking in a review were an architect is called to spot problems in the comments.
All developers must follow a design, that is actually a detail of the architecture. They have to stick to the best practices, that are actually enforced using an static code analyzer.
Now, we also have a technical lead, whose job it to take care of reviewing the daily decisions the developers make. He is to document any decision that may go against the design.
When the code review is to be done, language experts are summoned to take a look at how the design was implemented in critical spots. (You cannot review the complete code, the analysis tool has done the trivial work for you). They will check if the best ways to implement the solution with the language at hand were used (say, application of idioms).
Then, if the code passes the "well done" mark in terms of language and micro-design decisions, it is the turn of the "what-is-it-doing" review. How good is not only a matter of good language use, it needs to address the result (which is the most important thing), and not the code itself (which is by no means the product).
You then call the designer and/or Architect. Using a visualization tool to view the actual code as classes and relationships, you check were the code takes a different path from the original design. For each one of those variations, there should be a documented reason. That reason is either approved or a recommendation is given to solve the issue in another way. That may require refactoring at any of the three levels (code, design, architecture). Do not forget the smells we can spot when looking at the solution from a higher perspective, like dependencies and such.
Finally, the architect should also have a list of quality attributes the system must achieve. We may check for the specific places where those are actually implemented (a security check, possible performance bottlenecks) and may look at the code there to see if the implementation seems to achieve that quality requirement.
SO, to asnwer when is code good enough? I may say it needs to deliver what is was designed to do, in the way it was designed to do (or at least have a very good rationale of why it is not).
William Martinez











