Obviously, if you want a high quality product with a clean codebase and low defect counts, you need to be very careful and methodical in your approach to developing software. Ready-Fire-Aim is a sure road to disaster, leading to chaos and confusion. Not only that, but it speaks to a general immaturity and lack of professionalism of the development team and its members. That is, unless you iterate rapidly and continuously improve.
One of the most common points of extreme contention I find between Agile and Waterfall practitioners involves a heated debate about the appropriate time in the project’s life cycle to be making important decisions about the software’s architecture. In one corner, we have the Waterfall approach of Big Design Up Front (BDUF), and in the other corner we have the Agile approach of Emergent Design. I’d like to outline some of the key differences between the two design philosophies because I think the right choice becomes obvious when they’re contrasted appropriately.
Speed and quality are universally contentious. Engineers always choose quality, but claim to value speed. Business owners always choose speed, but claim to value quality. Each side is skeptical of the other’s intentions when their actions seem to contradict their claims. Why does such an ironic and contentious relationship exist between the funder and the implementer? This post is not a referendum on either side: it’s a bi-directional concession letter, between Competent Business Owner and Competent Engineer.
This week, an incident happened with Knight Capital when their “trading algorithms” allegedly cost the firm hundreds of millions of dollars. Within hours of the story, various camps have been quick to denounce the algorithms and the automation that was supposed to save the day. Of course, the problem is in automation, because automation is supposed to reduce errors and prevent outages and boost security and mitigate risks and improve the bottom line and make ice cream sundaes with a cherry on top. Except when it doesn’t, and now this latest mishap only adds to the argument against such automated practices.
If you’re a senior-or-above talent, you know how work longer hours without it significantly impacting your work product. For this, I’m talking about the 40-50 hour range. Most people start to fall off around the 50-60 hour range, and we all start producing crap around 60-80 hours. Beyond 80 hours, it probably time to look for a new job. Having said this, let’s focus on the 40-50 hour range. If your employer suggests or requires that you work these extra hours, it’s probably not going to destroy your home life, or wreck your sense of well-being, so the impact should be minimal, if not negligible. Why not work these extra hours? Because you’re not getting paid for them.
Nobody wants to manually test software. “That’s not true! I do!” you say, missing my point. If you think you want to manually test software, then you need to dig deeper into what that entails: To do your job well, every time any developer changes anything to any part of the system you need to re-test everything. Anything less and you’re not doing your job. If you’ve heard different then they’re lying to you. *That* is what Quality Assurance is – the assurance of quality. The only way you can be sure that some developer didn’t break something is to test the whole system again no matter how minuscule the change. On a simple mobile app, that’s not so bad; on an enterprise system, you may end up throwing yourself down a flight of stairs just for a change of pace.
Let’s briefly take a step back. Yes, we’re all very concerned with how best to drive software development. We love our methodologies and our philosophies — our little software calendar platitudes and acronyms. We love Martin Fowler, Kent Beck, Eric Evans, Bob Martin, so on and so forth. But really, what is the point? This article is for everyone who has ever been subjected to my ongoing ramblings and critiques of software, processes, and team dynamics. I’d like to try to offer you a moment — if ever so brief — of catharsis. These were my intentions. Here was my point.
In Working Effectively With Legacy Code, Michael Feathers defines “legacy code” as code without tests. I love this definition for two reasons: first, it provides a succinct, objective way to measure whether code is legacy or not; secondly — and this really is the main reason I love it — it asserts that any code, written by anyone, at any time, without accompanying tests, is legacy the moment it’s written.
As problem solvers, we dream of a positive vision of the future, based upon the belief that the challenges and problems we face are solved by good design. OK, stop the playback. Back in the real world, the dominoes occasionally get knocked down in sequences un-imagined and worse, in ways where our complex and richly-integrated systems cannot address. Some of it will be act-of-god happenstance, some will be introduced by the ever fallible humans, while others are just malicious intent. It’s a harsh reality, but that is and have always been the Internet in spite of funny cat GIFs. When you are creating a solution — from authentication to authorization — make sure the design takes some consideration for all intents, not just the ones derived from planned and expected user stories.
It’s not the easiest pill to swallow, and more importantly, imagine trying to convince the management team to not only implement an external security review program, but to provide incentives for the resulting discoveries — that’s right, we’re going to pay others for our mistakes. Yikes! Let’s face it, there will be bugs in software, despite development process, review and QA. Items will get missed, and unintended feature or behavior will creep into the code base. The systems have become complex. The interactions are not always planned or even manageable with 3rd parties. Likely, only non-developers won’t acquiesce to that simple truth. It’s an understandable sentiment by the business stakeholders, as their focus isn’t on design or implementation of complex application logic. However, there should be one common ground within any organization, and that is the need to be diligent stewards of their customers, and by extension, their customers’ information. Security is the bedrock of excellent customer service.
Would quality be better if there were no Quality Assurance people? Let’s face it, most engineers abuse QA. They write a bunch of crap they’ve never tested, declare it’s done to much fanfare, and throw it over the wall to QA while they sit back knowing it’s going to take QA at least a day or two to start writing up bugs – more than enough time to get in some solid games of foosball. Furthermore, once they have *said* they are done, the pressure is off of them, and on QA to find them, at which point the engineer can sit back and pick and choose what they feel like fixing under the guise of “triage”.