The Source for Java Technology Collaboration
User: Password:



John Reynolds

John Reynolds's Blog

Why is so much software so bad?

Posted by johnreynolds on February 26, 2005 at 03:24 PM | Comments (12)

Why is so much software so bad?

I've read or heard this question thousands of times, and I repeatedly ask this question myself (I am sometimes embarrassed to be a programmer when my non-techno-friends struggle with bad software). Robert Martin's blog entry on No Next Big Thing bemoans the sorry state of software quality, and prompted me to ponder this question again.

James Gosling's blog entry on Sharpening the Axe includes a confession that is a telling clue in our search for some of the causes for bad software. In Gosling's words

"Often tool building is far more fun than actually doing the job at hand."

Many of the great programmers that I know are more passionately curious about building tools than about using tools. Actually doing the job at hand is sometimes an afterthought... and that can lead to bad (over-engineered/convoluted/overly complex) software.

Note: I will be using the word "tools" very broadly; "scaffolding" and "frameworks" are tools in the context of this blog entry.

Tools fall into two broad categories:

  1. Tools that are built for the tool builder's use
  2. Tools that are built for someone else to use

James' blog entry talks primarily about tools that he needs (or wants) to accomplish a specific task. Frequently these tools are disposable. It would be great if we honed these "I need it now" tools to a fine edge and kept them stored in our toolkits for future use, but that doesn't happen very often. We tend to crank out "I need it now" tools with little thought towards "I'll need it again".

Corrective Behavior: When you find yourself tempted to build an "I need it now" tool, first ask yourself: "Will I need it again?"

If the answer is no, don't spent much time or effort on the tool. Building any tool is a distraction from implementing the functionality that you've been asked to deliver. Bad software can result from spending too much time in preparation, and not enough in execution... it's a balancing act.

If the answer to the question "Will I need it again?" is yes, then you may be justified in spending more time and effort on the tool. I say "may be justified" because there are a million and one caveats to consider. If you will need a tool again, then someone else may have already created a tool that you could use for the same purpose. Because we like to build tools, we don't always check around to find out if a tool is already available.

Corrective Behavior: Before building a tool, look for a similar tool.

Actually, you should get into the habit of looking for tools long before you need them. Outside the world of software, I am a hardware store junkie. I love to browse the Harbor Freight catalog and prowl the aisles of Home Depot. My wife has learned not to roll her eyes when I rave about gadgets for driving screws at right angles or hanging a picture at a 32.7 degree angle. Most of the tools that I come across I will never need... but every so often I save my self a lot of time and effort because I knew that a tool existed to accomplish a specific task

If you can't find a pre-existing tool and you do decide to build an "I'll need it again" tool, then you really have to start thinking about usability and reusability.

Tools that you will need again begin to resemble tools that you build for someone else to use. You have to start taking into account the learning curve needed to master the tool. You have to take into account the ways in which the tool can be misused. You have to start thinking about incorporating user feedback into your process for refining and maintaining the tool (With my fading memory, I won't remember building the tool, so when I need it in a few months I too will be a "first time user").

Corrective Behavior: Before finalizing a tool's design, explain to someone else how to use it.

The perceived quality of a tool has as much to do with how you use the tool (the tool's interface) as with how well it is built. You can craft a widget out of titanium alloy, but if the users can't figure out where to hold it they won't use it (and they'll probably tell others that you built a bad widget).

Many of the interfaces that we come up with for our tools are overly abstracted. We genericize our tools to the point of hyper-configurability. Configurability is great, but when we configure something wrong the result is often buggy software. Every layer of indirection between a requirement and the code that implements the requirement is an opportunity for introducing errors. Much of the bad software out there could be due to layer upon layer of slightly mis-configured tools.

Corrective Behavior: When building a configurable tool, spend time to simplify the configuration process.

Recently XML configuration files have become all the rage to the point where I am beginning to wonder if it is possible to write and deploy a Java application without authoring an XML configuration file. It's always going to be a judgment call with regards to what should be configured via XML, what should be configured via annotations, and what should be configured via customized code. Whatever your choice, you must consider the likelihood of configuration errors and take steps to prevent, detect, and correct them. Often times this will require the creation of a supporting tool. Often time this leads to the cycle of building tools to build tools that build tools. If any of the tools is buggy, the end-user product may well be bad software.

At this point I need to back-track and loudly assert that the tool-building related factors that I have discussed are not the primary reasons that a lot of software is bad. Shoddy requirements and poor management are certainly bigger culprits in many instances... but we always need to look at ourselves as part of any solution.

While writing this blog entry, I started thinking about professional standards and a professional code of conduct. Using Google, I did a quick search on "code of conduct" and came up with a link to the following: ACM Code of Ethics and Professional Conduct.

The ACM's code is lofty and noble in it's tone, and seems to borrow a bit from the Hippocratic Oath.

I am going to digress from my tool-building-centric theme and lift my final Corrective Behavior directly from the ACM code:

"Quality professional work, especially in the computing profession, depends on professional reviewing and critiquing. Whenever appropriate, individual members should seek and utilize peer review as well as provide critical review of the work of others."
Sounds like a good topic for a future blog entry....



Comments
Comments are listed in date ascending order (oldest first) | Post Comment

  • Bemoaning the sorry state of software quality is a complaint that comes back like clockwork and ironically often comes from industry veterans who, by their experience and time in the industry, should hold themselves at least partially responsible for it's current state. First, it's merely an economic factor. As long as there are people who will pay for bad software, it will persist. The fool in this picture isn't the lazy engineer, but the cheap or lazy consumer. I've rarely if ever found a bug in expensive gaming software. It works every time, hour after hour, leading me to believe the industry knows how to write quality software when it needs to. There are many examples in our industry where the quality, easy to use product lost out to the cheap but buggy alternative. Second, as you say “Many of the great programmers that I know are more passionately curious about building tools then (sic) about using tools.” I have a hunch that “most” was your first thought. Even you make the distinction that these developers are the “great programmers”...the hidden meaning being that the ones who stick to the task at hand are not great programmers. Why do you think this is the case? I think we somehow this type of behavior is rewarded in many cases. Think of a good tool, and a great developer's name comes to mind ( perl, junit, ant, struts, Fitness). I agree with your emphases on ethics and quality, but I think the winners, corporate or individual, are going to be the ones who spend more time, not less, on "I need it now tools".

    Posted by: tcowan on February 27, 2005 at 06:58 PM

  • Nope, your hunch is wrong. There is no hidden meaning in the phrase "Many of the great programmers that I know....". Some of the lousy programmers that I know like to write tools too :-)

    Posted by: johnreynolds on February 27, 2005 at 07:35 PM

  • A couple points: 1. tcowan says, "it's merely an economic factor". Sadly no metrics exist for measuring a programmer's quantity and quality of work. Atleast not in my work place. (writing at the risk of displeasing some people at work. what the heck! They are hard to please except through kissing their behinds and atleast a few are idiots.) Think about it. Most other professions - manual labor, lawyers, doctors etc have fairly well-defined metrics. 2. My humble opinion - In my application development, I don't use many tools, beyond plain old vi, and a few useful new tools such as ant. No, I don't use an IDE. Perhaps some people find it very odd and archaic but I am able to function without fancy tools. I have elicited remarks such as, "what! you don't use a UML tool?" and such. Alright, I am a mediocre programmer, perhaps. But I still don't think it is easy to define and develop a general-purpose tool. Some of the applications are fairly specific - for instance, in my current project, I find that a certain framework was introduced which isn't absolutely necessary. IMHO, not using external tools (that aren't absolutely essential) in an application, contributes to ease of maintenance in terms of fewer updates and so on. One "tool" that I have found absolutely essential is log4j, but there are some others that are not necessary in our application. My 2c.

    Posted by: rsm0001 on February 28, 2005 at 09:02 AM

  • "not using external tools (that aren't absolutely essential) in an application, contributes to ease of maintenance in terms of fewer updates and so on."

    I don't really disagree with this statement... depending on the nature of the "internal" tools that you incorporate into your application.

    Let me give you an example: My company developed an internal tool (framework actually) for validating user input. This tool does not provide much functionality beyond that provided by the Struts validation "tool".

    The Struts validation "tool" has been peer reviewed by many more eyes then our internal tool, and as our staff rolls over we'll be losing intimate knowledge about our home-grown tool. It will be easier to hire programmers who know Struts validation then teach programmers our in-house tool.

    In this case, I think we should have used the Struts "tool".

    Posted by: johnreynolds on February 28, 2005 at 11:02 AM

  • you cannot underestimate the economics of the software development. A lot of projects I have been involved wth had no way to judge or even estimate the quality of my (or my peers') work. Two "bad smells" are typically present: lack of massive, concentrated Junit testing effort and free reign given to developers to use (and abuse) whatever framework they wish. including rolling out their own.
    Tool building is attractive considering the alternatives. It is always a clean slate, uncontrolled, do-what-I-like activity. If I dont do tool building, the only way to "shine" on the team is to go deep into someone else's code, track and fix those little bug things, do annoying repetitive work - no fun at all.
    "Building your own" should be left to the project architect who better have good (and documented!) reasons to do so. It is amazing what happens when people stop for a sec and take a look at what is already available.

    Posted by: mgarber on March 01, 2005 at 07:05 AM

  • I think using tools is a small factor in software failure. The bigger issue is passing on software at various stages to different groups. I have seen great projects designed and implemented very well by GREAT software engineers. However, these projects are usually passed on to someone else at a later stage to implement new features. Code ends up being long spaghetti and out of sync with its original design. There are many factors here: either the new group does not understand the original design, non-qualified programmers, etc. Let's face it, nobody wants to maintain someone's code. I agree with tcowan, the game industry really shows us how to write good quality software.

    Posted by: tuthach on March 01, 2005 at 07:27 AM

  • I'm curious what it is that you think the game industry is on to. I'm totally ignorant, I don't often play computer games.

    Could the quality of games be due to the passion that game developers have for playing the games? I think that's likely. If you love playing games, you're going to be focused on the end-user's experience.

    Unfortunately, it's a bit harder to find programmers who are passionate about filling out on-line credit card applications ;-)

    Posted by: johnreynolds on March 01, 2005 at 08:23 AM

  • I'm interested in the No, I don't use an IDE. comment. I'd like to know why? I used to use emacs for all my editing but was persuaded to try IntelliJ. I wouldn't go back to editing java with emacs now. With all the help a good IDE provides why would you not want to use one?

    Posted by: alexmoffat on March 01, 2005 at 12:03 PM

  • There are several issues with why software is in a poor state. First, there are more programmers who know a language but not computer science. Second, there are too many languages that do the same things, but don't interwork. This means that the same things get written multiple times. This distracts ones attention from the real details. I see enough questions on enough programming and toolkit lists that express complete ignorance of software engineering or language basics, that I have to try hard not to just scream.

    Schooling seems to be teaching more about how to use computers, not how to write software. Such instructors think its better to teach how to use eclipse than how to write an eclipse. I wonder how many CS graduates can sit down and write correct implementations of:

    • Shell Sort
    • Balanced Trees
    • Hashtables with chaining
    • Disk hashing
    • Doubly linked list
    • Stack
    • FIFO queue - would the know to use a doubly linked list?
    • etc...
    Also, do programmers/developers/engineers know when to use these?

    Part of understanding when to use each of these is understanding what each does. There's the whole world of concurrent programming that Doug Lea has simplified through his Java libraries now in JDK1.5. But, watch that list, and you'll see there are some who have no knowledge of some of the concepts that the library addresses.

    Of course bad software also comes from choosing the wrong 'language' for expressing the solution to a particular programming problem. Some people still think that a language is only the semantics of the syntactic elements. They don't know how to layer a domain specific API on top of exising libraries. They have missed out on some important concepts. In many programming languages, you need to know how to recast your problem domain language into programming elements that are sound for the problem domain. You need to understand where the variability is and how the language's capabilities can be utilized to solve the problem, but also allow for future expansion. But, don't design the future. Instead, just provide the interesting plugin spots.

    I always design from the bottom up because I've learned that its the low level details that provide the challenges. Design these elements carefully. You'll then learn even more about them as you put upper layers on and discover how easy it really is to 'talk' about the problem using those concepts.

    Top down programming always insists that the outside interface is more important. Don't get me wrong, the visible API is the important part. But, just starting with that can blind you to things that the mechanics of the system will encounter which the API just can not provide a safe binding to. Typically, there is implicit state that you want to manage internally but which cannot be made idempotent.

    Posted by: greggwon on March 01, 2005 at 12:07 PM

  • IMO: The industry needs a formal apprenticeship system. Coding - like other work whose goal is to build/repair/maintain functioning artifacts - is a trade.

    Posted by: pmurray_bigpond on March 01, 2005 at 08:37 PM

  • I think there are a few problems in writing software, that writing games does not have: - the developer should know the domain he's writing programms for: game coders do - the developer should test the software by using it: game coders love to do that - the user interface should be usable and nice looking to attract users: for games thats normal - and so on... I think (and know from my company and colleagues) that these points lead to a lot of problems. The developer thinks the programm he coded is good, but the customer thinks different. And because the developer does not (or not enough) talk to the customer (because the project manager does that for him) he never gets the clue what the customer thinks and what he really needs/wants. That leads to bad software (apart from bad coded software). In game coding the developer is its own customer. So he tests his software with the eyes of the customer. This should a "normal" developer also do but mostly can't because he does not know how a customer "looks" on the software.

    Posted by: chbeer on March 02, 2005 at 01:07 AM

  • When the question of software quality comes up, the conversation usually turns towards the craft of programming. We hear about design patterns, best practices, methodologies, extreme programming, management techniques, better specs, better tools. The emphasis is on how the program is created, like a hand-crafted good. To improve programming we improve programmers.

    Yet as long as programming is a hand craft, where individual humans operate on individual lines of code, software will never be any better or more reliable than the programmers doing the coding. One line of faulty code, even one byte of data written outside of allowed memory, can crash a program. Imagine the fragility of a building or bridge if the entire structure could collapse due to one faulty rivet. Good craftsmanship can correct this only partly and requires a surplus of extremely dilligent rocket-scientist programmers. The solution is not to improve the craft, the solution is to design inherently stable systems.

    Fortunately software is not the first technology that has worked through these growing pains. Architecture, electronics, audio systems and other technologies have scaled up, and managed complexity through the use of discreet components that can be readily combined to create large structures. We have no good equivalent to this in software, and without it we'll keep beating our heads against quality control issues. While OOP promises encapsulation it actually does not provide truly encapsulated components. To fully encapsulate an object we need to extend the OOP model. I muse on this further in a post on my blog.

    Posted by: napier on March 28, 2005 at 08:16 PM



Only logged in users may post comments. Login Here.


Powered by
Movable Type 3.01D
 Feed java.net RSS Feeds