I know, I’m a few years late on this.
But still. Better late than never, right?
Typically I despise the “software development is engineering” analogy. The process of developing software is so very little like building a bridge or building a house (in any modern sense, at least) that it often seems to cause more harm than good to make the comparison in the first place. But last night Erin was watching a show on HGTV, and I realized that there is a rather striking analogy that makes sense:
Looking over poorly-written software is much like looking over a poorly-constructed house.
On the outside, the house may look fine; it may even be the nicest looking house on the block. If you talk to the people living in the house, they may say that they love the house, except for a couple of minor things that need fixing (after all, they hired you for something, right?).

Once you get in and start inspecting the house’s internals, though, you start to see problems. Electrical wiring is backwards. Gas lines are run through dangerous and/or illegal areas. Drainage is poor at best, and you see signs that the foundation has been eroding away. There are patches of insulation that are flat-out missing from the walls. Load-bearing structures aren’t built with the appropriate materials. The plumbing is a tangled mesh of rusting copper. The house is unsafe, and unless it receives a lot of attention from someone who knows what they’re doing, it won’t really be safe any time soon.
Software can be a lot like that. On the outside, it can look like a very attractive piece of software, and the users can really enjoy using it (except for a couple of things that they’d like you to change, but that’s easy, right?).

Once you get inside the code, though, you can find a fragile mess. Poor error handling, convoluted logic that doesn’t cover all the use cases. There are comments in the code that are less than useless because they’re totally wrong about what the code does or why it’s doing it. Application data isn’t always handled safely. The application tries to behave concurrently but most of the operations aren’t thread-safe. To top it all off, there’s no documentation and even less automated tests, which means you have no idea how the program is supposed to work, and even if you did know that, you would have no way to verify that it was working properly.
In both cases, when you take this information to the client, the typical response is going to be “but it works, why should I pay you to fix it?” Of course, when you’re talking about houses, the response is “because your house isn’t up to the code that’s mandated by law, and above that if some of these safety issues aren’t resolved, you and your family are exposed to serious risks to your health and safety.” When you’re talking about software, the best answer you can give is “Well, I know it hasn’t caused you any problems yet, but it’s highly likely that it will in the future unless you let me rework it for you.”
In other words, where the opinions of a general contractor can be backed by physical evidence and codes and regulations, even though the house appears safe, the opinions of a programmer can only be backed by the opinions of the programmer unless there’s a demonstrable problem with the software. There’s no easy way to convince a client that there are fundamental flaws with their code, and even if you do there’s no way to convince them it’s worth training unless they already trust you and have bought into your expertise on coding.
Wouldn’t it be nice if we - as an industry - had a set of codes and regulations we could leverage to improve software? I’m not sure what those regulations would look like, or how we’d enforce them - software developers can’t agree on how many spaces to use for indentation, much less on whether they should write automated tests - but I think it’s something worth thinking about. Nothing unnecessary or specific - no “you must use x testing library,” or “you must have all your software developers in one room,” because those only serve specific agendas. Nothing that requires ‘certification’ or anything else that can be used to make money; probably just some sort of open-source document that programmers can recognize as an authority on, generally, how things should be done. Imagine how much better our industry could be if we tried to standardize on disciplines that take steps towards preventing disaster projects, and were able to use those standards to convince clients that their software needs to be made better?
Would it mean that the client would always let us make these changes? Of course not. There’s a lot less risk in the statement that “your program might crash often” than there is in the statement that “your house might burn down.” Also, I’d like to hope that no codes we create would ever be legally binding. What it would do, however, is lend strength to what you bring to the client; rather than it being you saying “You should pay me to fix these problems that you don’t really understand, but trust me, they’re problems,” there can be an industry-sanctioned document that says “Here’s the problem this programmer is telling you about, here’s why it’s a problem, and here are the risks you should consider before you decide whether to let him fix it for you.”
Just a thought… maybe a crazy one at that. But, just like a contractor who comes in and works on a house, your reputation becomes tied to every piece of software you touch. Wouldn’t it be nice if you had some better tools to convince clients that the code they have needs to be fixed?
If we accept that code is design — a creative process rather than a mechanical one — the software crisis is explained. We now have a design crisis: The demand for quality, validated designs exceeds our capacity to create them. The pressure to use incomplete design is strong.
@commondream and I had a brief discussion about the merits of comments.
I have a serious problem with the statement that “good code doesn’t need comments.” It seems to me that this is mostly used as a crutch for laziness - after all, I already know what the code does and why it does it, so it’s boring for me to go behind myself and write documentation for it. If I say that it’s good code, though, and that good code doesn’t need comments, then I spare myself of all that work!

Personally, I think comments are pretty much always useful. That’s not to say that comments should be ubiquitous, just that there is a time and place for them (and the fact that you might want to use some doesn’t mean your code is bad).
Good code is a lot like good writing, for a lot of reasons. The one that I want to focus on, though, is that good code knows its audience in the same way that good writing does - it makes reasonable assumptions about the people who will be reading it.

Examples: if I’m writing a bit of code that a bunch of beginners might look at - a Rails plugin, for example, is going to be seen by a bunch of people new to Rails, perhaps, if it becomes popular - I should keep that in mind when writing the code. In this example, I’ll probably comment the code pretty heavily to make it easy for a newbie to follow why the code does what it does.
On the other hand, if I’m writing some niche mathematics library that’s only ever going to be used by people who are already fairly familiar with the subject matter, I probably don’t need to explain why I’m having to cross-multiply the beta matrices; at the very least, I shouldn’t need to explain the basics of the operation.

In short, there’s no universally right answer for whether you should use comments on any particular part of your code, just like there’s no universally right answer on when you should use SAT words in your novel or make Battlestar Galactica references in your blog posts - it depends on your target audience.
People who try to use C++ to build giant, hairy systems often wind up being giant, hairy programmers as a result.
A chef can detect every imperfection in their food. However, all of the attention on the kitchen means it’s easy to lose track of the basics – the margins, the repeat customers, the service – that make a restaurant sustainable. Our big lesson: focusing on the financial – not the code – builds a better product.
—
When tech startups == closed restaurants
I very much dislike financial stuff. Because of this, I’m OK with the idea that I’ll probably never run my own business.
Since leaving my old job maintaining an e-commerce site (not naming names), I’ve worked on four (vastly) different projects. Of those four projects, three have been launched to the satisfaction of the client and are now “live” production applications.
Don’t get me wrong, the point of this post isn’t to brag; if anything, these projects succeeded in spite of my contributions rather than as a result of my talent.
For two years and change I was maintaining two rather monolithic applications written in Java. In the year after I left, I’ve worked on 4 projects, using 4 different frameworks in 3 different languages. For the most part, once the projects are out the door, that’s it - they’re gone. No support calls, no arguments with operations employees, no maintenance. Each new project is a chance to learn from the mistakes of the last project, rather than being forced to live with them.
Managing one piece of software for years isn’t software development any more than managing one large building for years is architecture. There’s a fundamental difference between creation and improvement; sadly, most people new to the field (myself included) don’t appreciate that initially, and I think far too many companies are willing to exploit that.
To everyone who looked at me funny when I said I wanted a job doing “real” software development: this is what I was talking about. This is what software development should feel like.
For the record, I think that designing modularly is very important, and while Ruby provides built-in support for these modular patterns, we don’t see enough usage of them. However, we should not assume that the reason for the overuse of poor modularity patterns (like alias_method_chain) result from a lack of discussion around proxies, decorators, and factories.
— AbstractQueryFactoryFactories and alias_method_chain: The Ruby Way « Katz Got Your Tongue?
I started to write a long rant about how you have to actually love your job rather than just like it. Assume (for my sake more than yours) that it was a wonderfully concise and well-written blog post that would’ve inspired you to personal revelations beyond your wildest dreams.
I deleted that post and substituted it with these paltry paragraphs because about halfway through writing my post, I realized that Jamis had already said it better (and, of course, in a much nicer way).
Part 2
Part 3
Part 4
Go read those posts (they’re kind of long, I know, but totally worth it), and you should understand where I’m coming from when I say “If you ‘like’ coding, I probably don’t want to work with you.”
If you don’t then let me know and we’ll talk.