Summary
In most commercial projects, "code quality" doesn't matter because code is seldom the end-product of the development effort - it's the binary that we ultimately ship. Total product quality matters, and process and skill weigh more than code quality in determining overall product quality.
Advertisement
In a recent blog post, Bill Venners ponders if you can "write quality code quickly."
Some of the ensuing discussion betrays an unfortunate misunderstanding about code
quality. To illustrate, I have almost never met a developer working on real-life,
production software in a business environment who was completely satisfied with the
code he was working on.
If anything, I almost discern an inverse relationship between how satisfactory a
piece of code is to the developers working on that code, and the amount of money that code makes for those developers' employers.
The other day, for instance, I was
having brunch with a friend who toils for a living on the crucial server component of one of the world's largest and most profitable database companies. He lamented about
the ugly naming conventions used in that huge code base, and how that makes it hard
for developers to work on the code. Yet, that same codebase is good enough to
generate several billion dollars in revenue for that company.
I think much of the eternal developer lament about code quality has to do with the
strange and highly unusual job of the software developer. If you're a musician, all
day long you practice and work on the actual output of your job, the music. You can
work to shape every note and phrase to your liking, and, with luck, those practiced
nuances will come off the same way during a performance or recording. If you are a
carpenter, you spend your day working on the actual chair or cabinet that is the
final output of your work. As a physician, your work is performed directly on the
main object of your profession, the patient.
As a developer, almost nothing you work on ever leaves your development environment
or the close confines of your development team: What you ship is the binary, not the
source. Unless your product is, or includes, the source code, almost no one outside
your team ever sees - or cares about - the source code you spend the precious hours
of each day writing.
It follows that few people outside your close team members ever care about the
quality of that source code. And most compilers don't care about source code quality, either - how you name your variables, how long and clean your methods are, the clarity of your object model, or even the algorithms you use, are of little interest to the compiler that can happily create an equivalent binary from ugly or pretty code.
Of course, we as developers must care about code quality, since we spend most of our
waking hours working on code. And, as every good craftsman, we strive for quality. A physician would want to practice high quality medicine, or any carpenter worth his
salt would want to produce a quality staircase or chest. As developers, we also like
to produce and maintain a high quality code base.
The trouble is, a quality code base often doesn't matter in terms of our final
output, because the compiler is there to mediate - it obliterates ugliness as much as it wipes away beauty. And users care only about that final, binary output. For instance, as you read these words, you care little about the quality of the code that the Java compiler translated to the binary version of this JSP page.
When we spend time to make our code high quality, we justify that effort by saying that the work would provide some business benefit down the road. The trouble is,
code quality, by itself, seldom results in any measurable business return on
investment, as many commentators on Artima have observed. The database company my
friend works for, for instance, may have "ugly" or hard-to-read code, but that code works just as well. Instead, that company is better off focusing on overall product quality than on code quality.
And total product quality, as Edwards Deming noted, is not the result of merely improving the quality of a single activity, but is rather the outcome of a set of processes focusing on the quality of the total output. In this case, that total output is the binary we ship. Developer testing, agile development methods, quality assurance, continuous integration - these are all processes that facilitate a high quality of total output. Code quality is but a small part of that effort. An organization can
get a better return on investment from focusing on the processes that lead to a
quality product, than by placing a great deal of emphasis on code quality.
Managers, intuitively or by learning, seem to understand that - to the chagrin of
developers, who must work on the level of the code day after day. That's sad news,
because it means that we, developers, are doomed to eternal complaint and frustration about code quality.
> If anything, I almost discern an inverse relationship > between how satisfactory a > piece of code is to the developers working on that code, > and the amount of money that code makes for those > developers' employers.
I'd love to see your metrics.
> The other day, for instance, I was > having brunch with a friend who toils for a living on the > crucial server component of one of the world's largest and > most profitable database companies. He lamented about > the ugly naming conventions used in that huge code base, > and how that makes it hard > for developers to work on the code. Yet, that same > codebase is good enough to > generate several billion dollars in revenue for that > company.
Do you think their software maintenance costs might be lowered if the names were improved? Wouldn't they then earn even more money, and be able to make more frequent releases, adding even more features? How much money, time, and opportunity are they losing because of the bad naming convention?
What if another company, with better software, manages to start competing with them. As the two go head to head, which will be able to react quicker? Which will be able to get more features added? Might this company find itself #2 or #3?
> As a developer, almost nothing you work on ever leaves > your development environment > or the close confines of your development team: What you > ship is the binary, not the > source. Unless your product is, or includes, the source > code, almost no one outside > your team ever sees - or cares about - the source code you > spend the precious hours > of each day writing.
As you pointed out, the folks who maintain it care a lot. You will care if you have to maintain it. You will care if you have to debug it. And you cost money. The business cares about that. The Business also cares that it's products are easy to maintain, and easy to change. The business expects that you are a professional producing high quality.
> It follows that few people outside your close team members > ever care about the > quality of that source code.
You have never had to maintain anyone elses code, have you? "Your" code, does not stay "yours" for long. Others have to read it, change it, fix it, rework it. And they'll have brunch with their friends and tell them how awful that code is, and how much time they are losing because it's so awful.
> The trouble is, a quality code base often doesn't matter > in terms of our final > output, because the compiler is there to mediate - it > obliterates ugliness as much as it wipes away beauty. And > users care only about that final, binary output.
Users care about new releases. Users want new features. Users want zero defects. These things are made more difficult by ugly code. So users care about quality code.
My cell phone crashes from time to time. I care about that. I want it to stop crashing. I don't want to have to reboot my phone. Sometimes the crash is so bad that the software has stopped polling the off switch, and I have to pull out the battery. I care about this. I wish it didn't happen. I swear at the programmers every time it happens.
Every time windows crashes, I swear at the programmers. Damned unprofessionals!
> When we spend time to make our code high quality, we > justify that effort by saying that the work would provide > some business benefit down the road.
No. We don't have to justify it, because we know that it takes less time to do things right, and more time to do things wrong.
> The trouble is, > code quality, by itself, seldom results in any measurable > business return on > investment, as many commentators on Artima have observed.
They are wrong. Code quality results in very measureable business ROI. The code is done quicker, it can be more easily maintained, it is easier to change, it has fewer bugs. The cost of these things is easy to understand.
Sloppy code is more expensive in time, defects, and flexibility, than clean code.
> Instead, that company is better off focusing on overall > product quality than on code quality.
That company would be better off focusing on quality in *all* it's actions.
> Managers, intuitively or by learning, seem to understand > that - to the chagrin of > developers, who must work on the level of the code day > after day. That's sad news, > because it means that we, developers, are doomed to > eternal complaint and frustration about code quality.
No. Good managers will not tell us to produce crap. If a bad manager does, we do not have to obey. We are professionals. We will do professional work. We know that the only way to go fast is to go well.
I have been in environments where (lack of) code quality mattered; where tomorrow had been blissfully mortgaged to make today a little easier, and the codebase was almost unmanageable with the reams of duplicated code, hacked around bugs, and byzantine flow of control.
Given a choice I'd much rather code in a sane environment. At some point those who aren't willing to wade through sewage leave -- I have done it before and will do it again if need be.
I also work hard to make sure I leave a code base a little better than I found it. It really does pay off in the medium and long term.
Your example of an ugly (aka out of fashion) naming convention not being worth changing makes sense, but that minor blemish is a far cry from the mess of code which goes into some projects.
To me perfection in code is probably not worth pursing, but being pragmatic about the costs associated with really bad code (developer attrition being one of those costs) is well worth it.
To take the carpenter analogy a step further: there is no shame is producing a really nice step stool, and I want to work with developers who would rather do that than produce a shoddy wardrobe that won't even stand upright.
As far as the compiler goes, it is no mediator. It may hide syntax of the bad code itself from the customer, but it certainly won't hide the bugs.
Finally, a manager complaining about developers whining about code quality is a sign of a dysfunctional organization.
A manager should respect the developer who strives to improve the quality of the product and the associated code just like the developer should respect the manager who strives to align development focus with business needs.
Code perfection is a myth, but making code livable is a realistic goal.
> Do you think their software maintenance costs might be > lowered if the names were improved? Wouldn't they then > earn even more money, and be able to make more frequent > releases, adding even more features? How much money, > time, and opportunity are they losing because of the bad > naming convention? >
Another way to look at it is that, say, you're now spending an extra $1000 per month because of the ugly naming conventions. To clean that up would cost, say, $5000. So spending $5000 now would result in a cost reduction of $1000 for each month after the job is done. Now, suppose you could spend that $5000 on creating a new feature instead that could generate you $2000 per month. How would you spend your $5000? If you spent it on the new feature, you could be ahead $1000 per month, even if living with the ugly code. I know that this is a headache for developers having to maintain that code, but that's a reality anyone with fixed resources has to deal with.
> My cell phone crashes from time to time. I care about > that. I want it to stop crashing. I don't want to have > to reboot my phone. Sometimes the crash is so bad that > the software has stopped polling the off switch, and I > have to pull out the battery. I care about this. I wish > it didn't happen. I swear at the programmers every time > it happens. > > Every time windows crashes, I swear at the programmers. > Damned unprofessionals!
You just illustrated the point I was trying to make: Even though your cell phone crashes, you still find it useful. In fact, you yourself support that less-than-perfect cell phone software by subscribing to the service month after month.
I have had to deal daily (I mean *many* times a day) with customers who had one or another kind of problems due to Windows. Just today, I spoke with a customer who was literally ready to murder because he lost a customer due to viruses and spyware that rendered his computer useless at a crucial moment. Yet, this very customer, and millions like him, support that OS because, on the whole, they still find it more useful than using a pencil and paper. If the vendor of that OS waited for the iterations to reach defectless quality, this customer would still be using paper and pencil. On the contrary, this company made more money than anyone else in history by knowing just what the lowest tolerable quality was to ship their code.
> Thanks for your great comments. > > > Do you think their software maintenance costs might be > > lowered if the names were improved? Wouldn't they then > > earn even more money, and be able to make more frequent > > releases, adding even more features? How much money, > > time, and opportunity are they losing because of the > bad > > naming convention? > > > > Another way to look at it is that, say, you're now > spending an extra $1000 per month because of the ugly > naming conventions. To clean that up would cost, say, > $5000. So spending $5000 now would result in a cost > reduction of $1000 for each month after the job is done. > Now, suppose you could spend that $5000 on creating a new > feature instead that could generate you $2000 per month. > How would you spend your $5000? If you spent it on the new > feature, you could be ahead $1000 per month, even if > living with the ugly code. I know that this is a headache > for developers having to maintain that code, but that's a > reality anyone with fixed resources has to deal with.
I think the naming conventions is a straw man, but I'll still play.
Let's take only a slightly more long term view. Let's pretend the cost per code wart is $1000. The naming convention is 1 wart so the cost is $1000 per month.
Let's pretend you start with $5000 of capacity, but you get to add %20 of increased revenue as more development capacity (probably an unrealistically high amount of additional income to sink back into development costs).
So to pay for your $1000 monthly "wart interest" you need to bring in $5000 a month.
Even worse, every monthly "wart interest payment" cuts down on what you can do the next month.
Let's assume that $5000 is your monthly development capacity. If you add 5 features and leave 5 warts, you have absolutely $0 of developer capacity. Even worse the 5th feature takes 100% of your capacity for 5 months (at that point 4/5s of your capacity is servicing the interest on the 4 other warts you've chosen not to fix).
But wait, you say, what about the $10000 a month my $2000 of income x 5 features bring in? If your development organization keeps 1/5 of that for engineering, that has only added on $2000 of capacity.
You would of course, do two new features (1st feature takes 2.5 month, 2nd feature 5 month) and again have virtually no resources left for new features.
Each feature you add quickly adds about $1000 of "wart" that needs to be refactored/cleaned up to support it cleanly in your architecture.
In other words, each new feature makes the codebase bigger and harder to maintain since a new feature might add a manual build step, more code to search through to track down a bug, slower install, higher associated support costs (new code usually has more bugs found early in life), or something else: in general more equals more to development cost.
> > Instead, that company is better off focusing on overall > > product quality than on code quality. > > That company would be better off focusing on quality in > *all* it's actions.
A hallmark of a great organization, in my opinion, is its ability to create something robust and resilient out of unreliable components.
As a business grows, you will inevitably have to hire all sorts of programmers, and you will have to make use of their work. Some of them will create great quality code, others will write terrible code. As an organization, you must choose wisely where to spend your resources. You can aim to hire only the best programmers, or you can spend a lot of resources on improving the code quality of each programmer. These all must be done. But you can also invest resources into creating processes and systems that ensure that, on the whole, the sum-total of all the code created adds up to something more robust than the individual parts.
A friend of mine worked at IBM a while ago on one of their operating systems projects. He said that each programmer saw only a small part of that huge codebase, and that the code he worked on wasn't that great quality. However, IBM had systems in place that ensured that the total output would be of extremely high quality - when all those little pieces were all tied into the system, they had processes that ensured an excellent total product quality.
That's similar to a cluster of commodity PCs: Each node might not be of very high quality. But the cluster software, the system as a whole, is highly robust. You can choose to invest in the nodes themselves (buying more expensive PCs), or you can choose to make the system as a whole smarter. Now, commodity clusters are eating into the lunch of expensive machines, and large scalable systems designs (such as Google's clusters) favor a cluster of cheap, less-reliable PCs than fewer but more expensive (presumable more reliable) machines. The key is that the system as whole that adds up to more than just a sum of its parts.
So, we can focus on code quality, or we can focus on creating the system in an organization that acts as a cluster manager, ensuring that all those varying levels of code add up to a high overall product quality. I was advocating a focus on those processes in my blog.
> I think the naming conventions is a straw man, but I'll > still play. > I was at the table when the person Frank was referring to was telling the story about the function names. It isn't a straw man and is likely worse than you imagine. The trouble wasn't poor taste in choice of names, the trouble was that in the early days of the codebase they had a requirement to support some compiler that only allowed a maximum of eight characters in a function name. There was no concept of namespaces or packages or fully qualified names either, so the first four characters were allotted to essentially the namespace, and the only last four characters were available for the function name. This is a huge program whose function names I imagine look something like fjasoend, slegpade, and pwfoawmx. I can't imagine how much time is wasted trying to read that code, but given the size of this company I'm sure it is way more than $1000 a month.
> Let's take only a slightly more long term view. Let's > pretend the cost per code wart is $1000. The naming > convention is 1 wart so the cost is $1000 per month. > > Let's pretend you start with $5000 of capacity, but you > get to add %20 of increased revenue as more development > capacity (probably an unrealistically high amount of > additional income to sink back into development costs). > > So to pay for your $1000 monthly "wart interest" you need > to bring in $5000 a month. > > Even worse, every monthly "wart interest payment" cuts > down on what you can do the next month. > > Let's assume that $5000 is your monthly development > capacity. If you add 5 features and leave 5 warts, you > have absolutely $0 of developer capacity. Even worse the > 5th feature takes 100% of your capacity for 5 months (at > that point 4/5s of your capacity is servicing the interest > on the 4 other warts you've chosen not to fix). > > But wait, you say, what about the $10000 a month my $2000 > of income x 5 features bring in? If your development > organization keeps 1/5 of that for engineering, that has > only added on $2000 of capacity. > > You would of course, do two new features (1st feature > takes 2.5 month, 2nd feature 5 month) and again have > virtually no resources left for new features.
I agree that over time that gunk adds up, and that, eventually, the system can become monstrously expensive to maintain.
But what are the options? Say, I have only $5000 in the bank. I have N customers willing to pay for this new feature. So what are my options? I can spend the money cleaning things up, and not implementing that feature. Or I can go ahead implementing that feature, knowing in the future I will have to deal with the consequences. Or, I can re-write the code from scratch. Or, I can just jump off a cliff. Which option would you choose? If you are a CEO of a company with fiduciary responsibility to your shareholders (or to your wife and kids), what option is most responsible? I can tell you that I would choose implementing and selling that feature. Maybe I would try to stay up all night for a couple of months and re-write the software, too...
OK: code is fed to compilers to produce the binary we ship, but it is also read by software designers who need to understand it so that they can fix it, or extend it. In the latter case, the need for understanding is paramount, if the code is to continue to be understandable and extensible. As Dick Gabriel has been saying for years: if you're a programmer, you're a writer. And if your writing is poor, your peers won't understand your ideas, nor give them the credit they deserve. They'll refactor or rewrite your code so that they *can* understand it.
I could ramble on much longer, but I've made the point that the initial post overlooked, I think.
On the code quality article, he's missed the point in a big way. First off, the binary is not the end product, it is an implementation of a functional set, which is the _actual_ product. One might argue that Toyota produces cars - Toyota produces transportation, the car is an implementation of that function. If hover vehicles become the world standard for personal transport, Toyota will create an implementation that delivers the functionality that they sell - personal transportation. Adobe produces Photoshop, a bundle of functionality for manipulating digital images, the binary is the implementation of that product, but the customer _buys_ the function.
The reasons behind quality coding are no more artistic than good electrical and mechanical design in a car. Quality code minimizes errors in the function set and insures a shallow learning curve for future functionality enhancements. The consumer may never see the source, just as he never sees the schematics or drawings for a car, but he does know how much he paid and does know whether or not the functions worked as advertised.
Although managers may intuitively understand that the actual end product of their team's effort is not the source code, they sorely miss the fact that the functionality _defined_ by that source code _is_ the end product. As source code becomes more complex, obtuse and difficult to understand, the functionality defined by that source code becomes more diffuse, unpredictable and difficult to understand and its future uses become more limited and costlier. Just as poor drawings and schematics would result in a poorly functioning car and would result in a higher learning curve for cars designed from the same priciples, poor coding results in a poorly functioning application and higher costs for derived products. It would be rediculous for a car manufacturer to poorly define the manufacture of his car, why isn't is the same for software? The answer is that managers don't yet understand that poorly designed code _does_ result in a bad product, even though the customer never sees the source.
Coding costs and recoding costs more; quality source results in a positive product life cycle with a higher profit margin and lower development costs for future products.
> If anything, I almost discern an inverse relationship > between how satisfactory a > piece of code is to the developers working on that code, > and the amount of money that code makes for those > developers' employers.
I haven't seen anything like this. In my company, we have two systems, and the one with most messy code has been the one that has cost us most to develop on (as well as being overall buggy and unstable), compared to the return.
> And total product quality, as Edwar ds Deming > noted, is not the result of merely improving > the quality of a single activity, but is rather the > outcome of a set of processes focusing on the quality of > the total output.
> In this case, that total output is the > binary we ship. Developer testing, agile development > methods, quality assurance, continuous integration - these > are all processes that facilitate a high quality of total > output.
The point is, in order to be able to do the above things efficiently and effectively, you need to keep the code in shape, i.e. having a good code quality. So code quality is actually the basis, as well as the outcome, of the above practices.
> Code quality is but a small part of that effort.
I disagree, as explained above.
> An organization can > get a better return on investment from focusing on the > processes that lead to a > quality product, than by placing a great deal of emphasis > on code quality.
It's hard to develop code, and therefore a quality product, unless the code is reasonably in shape, and messy code can therefore be very costly to work with, in many ways (too long time to implement features, too buggy and unstable, leading to too expensive development, and risking lost sale and opportunities).
> As Dick Gabriel has been saying for years: if > you're a programmer, you're a writer. And if your writing > is poor, your peers won't understand your ideas, nor give > them the credit they deserve. They'll refactor or rewrite > your code so that they *can* understand it.
Yes, indeed. The problem is, though, that different people understand different things. If you and I have different ideas about how the code base should be (for instance, if you understand patterns and I don't) we may make very different judgements as to the 'quality' of the code. You might see flexibility where I see complexity. You might see mumbo where I see a logical naming convention. However, in both cases the code is identical. Therefore 'quality' is not a property of the code but is a property of the programmer's analysis of that code.
Going back to what you wrote above. All the blame is being heaped implicitly on the author of the code. The fact that some others may need to rewrite the code so that they understand it is not the same as saying that they have improved it. Their poor understanding of the code may simply be lack of experience or because they didn't pay enough attention at college and now can't recognise quality code when they see it. Is that the original coder's fault? Maybe the code should be accessable to such people, maybe not. It's a judgement call based on circumstances. In short, you cannot measure the 'quality' of a piece of code independently of the person making the judgement.
"If anything, I almost discern an inverse relationship between how satisfactory a piece of code is to the developers working on that code, and the amount of money that code makes for those developers' employers."
I think that this relationship is real, and easily explained.
Programs are subject to natural selection. If code is of a poor quality, and is difficult to maintain it will normally get scrapped and be rewritten.
However, if that code is for an important activity, then the company will endure the poor code because of the benefits. After all, what benefits are more important than revenue?
Since the code quality is low, it will be highly resistant to change. The faults will remain without being addressed.
This means that when looking at high revenue applications you will find a higher proportion of applications with poor quality code.
The situation gets worse. The code will often encapsulate business logic that would have been common knowledge within the organisation at the time of applications original development. As time goes on subsequent generations rely on the system rather than developing the skills for themselves. After a couple of generations there is vital business knowledge that is only present within the application. Since the application is poorly written, extracting that knowledge is nearly impossible.
This means that given two applications performing the same task of strategic importance, the one with the poor quality code is more resistant to change and replacement.
In the software jungle, bad code is more likely to survive than good.
Flat View: This topic has 46 replies
on 4 pages
[
1234
|
»
]