“The Daily WTF” has been on my daily reading list for a long time, and I do read it every day. Last week the site changed its name to “Worse Than Failure” and kicked off with an interesting post by Alex on the new name and how it applies to all the programmers that read the site.
I wish more computer science professors would try to get Alex’s message across. After my Microsoft internship (which I’m flying out to Washington for at the end of the month), I’ll have only a few classes left before graduating. The four years I’ve been here so far, only one professor, Jeff Salvage, posed the question of whether software that’s poorly designed but is working to the client’s specification is a success or not.
If it’s not maintainable, impossible to enhance, not scaleable, it’s a failure even if it works. Anyone that’s worked on software for someone other than themselves probably knows it is rarely going to be static — there will always be feature requests, there will always be changes, there will always be bugs. If the software wasn’t designed properly up front, each change is going to introduce redundancy, hacks, and more bugs. Eventually the code base won’t be able to handle more change and has to be rewritten entirely.
I’ve had my share of failures that I’d like to put in writing so I never forget. These are all pieces of software that were considered a success by the clients they were developed for and their users, that made it to production use or even commercial sale.
The CRM/SFA software I wrote for Access 2 Vendors at the end of high school and the beginning of college was a failure. It was written in PHP and MySQL before I was competent with either and before I had any education in software design. I had no requirements when I started the project, and each ability it was to have came in a weekly e-mail. All this added up to very little design at all, starting over half way through the project to remove snowballing redundancy. It was coded in entirely procedural style, with no database abstraction, horribly suboptimal database queries and, in the end, way too much redundancy. Eventually I had to cut off the project when it simply couldn’t bear more features without another rewrite. As far as I know, there are commercial users of the system, but it runs awfully slow and will probably never be picked up by another programmer.
The custom “shopping cart” I wrote for The Math Forum. PHP was not an option in their environment, so I wrote it in Perl, again prior to any education in design (at that point, after my first year of college, I had only C++ programming courses behind me, nothing higher level about what and how to code). I invented my own “framework” which involved separating the “UI stuff” from the “database stuff”, essentially through duplicating the same logic in two places, processing form submissions to decide what to show next in one place, and manipulating the database in another place. All that got me was two places to edit each time something needed to change, and no less code coupling and no more maintainability. It’d probably be better to rewrite it from scratch than try to edit it to change the flow of their purchasing area — although I doubt they did.
The second version of W3Counter. The first version of that service was based on a commercial script I found through HotScripts. The second version was my attempt to add new features by keeping the core code base of that, which in itself was a huge failure in design terms, and try to “stick on” my new code. There was no structure, lots of copying and pasting, and lots of hard-to-see dependencies that would break the whole service if one part were changed. It worked, but barely. The third version was a success (and its performance issues are simply a limitation of hardware due to signing up too many thousands of users; I’m confident in both the software and database design).
The “missing translation reporting” feature I added to DuPont’s Global Reporting System. I can’t take credit for the failure of the rest of that system. It started out on the right foot a few years before I worked there — a solid, modular, expandable design. Yet through switching programmers every 6 months, many of them being inexperienced college students, and bringing in remote developers unrelated to the project to build new modules for it, the design principles the software started with were soon abandoned. Code was duplicated, old programmers used to writing COBOL for DuPont’s mainframe tried to reproduce their style in C++, and logic was split between “expert system” rule files and hardcoded conditionals. My contributions, in general, were good — fixing other programmers’ mistakes, removing duplication, contributing clear and maintainable classes with documented interfaces and low coupling. But the request for a way to report on “missing translations” was a failure — it needed to touch on almost every class and every file in the software, and I wasn’t able to design something that could do that well.
Looking back on some of the code I wrote just a few years ago, it’s hard to imagine writing it. It’s hard to imagine choosing to design software in those ways. It’s hard to imagine ignoring efficiency, ignoring security, and duplicating so much logic. But realizing that while all that code I wrote made it into use, and was considered a “success” by others, is actually a failure, will keep me from repeating the same mistakes again.



Jason
March 9th, 2007
Nice post Dan… good to hear from you again