I almost wrote this article not about McConnell, but Microsoft Press. Why? Because developers always have something to learn, books have been a great way to share information for centuries, so reading about computing is central to the software engineering experience. If you do not believe me, reflect on the activity you are undertaking right now, reading an online magazine about computing.
You can tell the seriousness with which a platform company treats its developers—or its “developers, developers, developers”—by the tools, knowledge and support it gives them. Where some companies release their API documentation in bound form through a recognised publisher, Microsoft just went and started their own book imprint. Not to bind their header comments between two boards, but to support professional programmers whatever their stripe (though maybe bear in mind which company has your back when choosing your technology, please).
Am I over-selling the importance of Microsoft Press, though? Steve McConnell, in Code Complete, 2nd Edition (2004, Microsoft Press), cites DeMarco and Lister’s Peopleware when he tells readers “one book is more than most programmers read each year.” He recommends trying to get through one every two months, as well as journals like IEEE Software, Communications of the ACM, and the now defunct and much-missed Dr. Dobb’s Journal. The “software developer’s reading plan” at the back of the book contains 5 introductory-level books, 8 intermediate-level, and 7 leadership-level. It would take the median programmer (at least in 1999 when Peopleware was written) over 20 years to follow the plan, but a little over three years at McConnell’s suggested rate. As long as you read CC2E first to know how quickly you are supposed to be reading!
Coincidentally, I left university to look for a job (which I found in the very room where I conducted my job search) in 2004, the year CC2E was published. Within a couple of years, when it was clear that my ability to solve problems using a computer was being hampered by my home-grown and BASIC-honed techniques at expressing computer programs, a manager gave me a copy of Code Complete. And the rest, as they say, is history.
There is lots to critique about the book, of course, particularly in 2020. Writing at the start of the Agile revolution, McConnell does not have much to say about agile practices or methodology (two entries in the index, in fact, both pointing to single-paragraph descriptions of books; there is no discussion of agile in the main text). Sure, all of the parts are there—there is a distinct shift in the discussion of change management and risk between the first edition and the second, for example—McConnell acknowledges that the different activities in software construction occur in parallel, and that the earlier a change is handled, the cheaper it will be. But he never quite gets to the conclusion that software need not be “measure twice, cut once”; that unlike carpentry, software has a limitless supply of infinitely malleable wood.
In some of the places where McConnell uses multiple citations to make a claim about software engineering, other writers have found the citations based on questionable data or not generalisable to the way most software is written, particularly “classic” studies from the 1970s looking at programming batch systems. But we will save that story, because a future instalment of the Programmer’s Library will cover one of those books in detail. It is more interesting than it sounds!
There is also lots to recommend the book: in fact, in the 16 years since it was written, nothing else comes close. I still use and recommend practices described in Code Complete. I have internalised most of the ideas about code organisation and conception. When I see someone who reminds me of mid-aughts me, this is one of the books that springs to mind.
Other books have come and gone that try to do bits of what McConnell does here, with varying degrees of success. Robert Martin’s Clean Code on low-level design teaches similar ideas but with less intellectual rigour. The same goes for his Clean Coder on the practice of being a developer, though this is a more contested field with good showings from Pete McBreen (Software Craftsmanship: The New Imperative) and Hunt & Thomas (The Pragmatic Programmer). But none of these come close to supplanting CC2E as a manual for turning a programmer into a software engineer, and the realities of the software publishing business in 2020 mean that no replacement is likely to show up soon.
If all Steve McConnell had done was write this one book, his would be a significant contribution to the field. Even among the MS press books on software requirements, object thinking (not OOP), secure software development, solutions architecture, and more, this is a stand-out work. But he was and remains a prolific author, so now we turn to the rest of his library.
We will start by going back from 2004 to 1996. After the first edition of Code Complete, McConnell wrote a book about improving the capability of software teams to successfully deliver working software, ways of so doing he had uncovered by doing it and by helping others to do it. This book was Rapid Development, as distinct from the then-popular fad of Rapid Application Development. Rapid Development was explicitly not “programming, motherfucker”: an exhortation to just get down to coding as quickly as possible. Rapid Development was the (then, and from what I have seen, now too) groundbreaking advice that you should maybe align your development practices with your customers’ expectations and needs, and that doing so will help you give them what they need faster. This book had many recommendations for developers and managers to adopt on their team, including early and continuous delivery of working software through iterative, evolutionary development; continuous collaboration between the software team and the customers throughout the project; frequent feedback on the status and risks and reprioritisation so that the biggest risks are always next to be addressed; and more.
If this all sounds like it actually is agile software development, expressed four years before the Snowbird ski trip, that is for multiple reasons. Firstly by the time the manifesto was written, there was already broad understanding (at least among the more experienced and expert practitioners of software delivery) that the ideas of iterative, incremental development were transformative to the capabilities of software teams, there just was not yet a common banner under which all of the people calling for this could march. Secondly it is because I have been selective in my presentation of what is in Rapid Development: one of the “case studies” features a team who fail because they integrate their work too early, before all of the modules are fully tested and debugged, and this causes schedule slippage. Nowadays we recognise integration as one of the risks that we should mitigate by early and continuous monitoring; thus continuous integration.
But mostly it is because agile software development has been hollowed out since its introduction at the beginning of the millennium. Ask many development teams what they understand by Agile in 2020 and you will get a list similar to the highlights of Rapid Development I gave above: incremental and iterative delivery, customer involvement on the team, frequent retrospectives and feedback. That is not the entirety of the story, that is the Project Managers’ Declaration of Interdependence (originally published on Alistair Cockburn’s site in 2005). Agile software development also included a number of technical practices, not explicitly called out in the manifesto, on the basis that what we do changes more frequently than why we do it.
We have already mentioned Continuous Integration, and developers might readily mention Test-Driven Development (and maybe its more agile siblings, Behaviour-Driven Development and Acceptance Test-Driven Development, which remind us that software is done not when the tests pass, but when the software does what the customer wants from it). Some may begrudgingly allow daily stand-up meetings as an agile practice, though they may grumble. But how about user stories? Those are a technical practice, and an example of specification-by-customer-conversation. Domain-Driven Design encourages a shared vocabulary between the software team and the customers, enabling those conversations. A review of agile practices in scientific software development lists 35 practices explicitly mentioned in the Scrum and XP methodologies. Of those, I informally count 22 technical (or at least not purely project-management) practices, and I would also suggest that those technical practices are the ones most patchily adopted across the industry, based on my own experience in many teams that describe their work as “Agile”.
Rapid Development gets a bye on some of those practices on the basis that they had not been invented in 1996, but also because McConnell makes a much more general and much more useful argument: technical practices are not guaranteed to improve your ability to deliver working software to your customers. Indeed adopting new practices on a new project is likely to reduce your control over and understanding of the project, thus harming your ability to communicate effectively with customers what you are capable of, how much it will cost, and how long it will take. This incredibly simple and important notion has been rediscovered many times in the industry, and is currently usually cited in the form of “innovation tokens” from Dan McKinley’s choose boring technology.
CC2E gets a bye on its short shrift on Agile for the innovation tokens reason: before the agile-industrial complex took over and made agile all about hiring scrum masters and producing burn-down charts, it was a shorthand for a lot of project management and technical practices and there was not yet compelling evidence that taken together, those practices improved the life or capability of a software engineer.
Maybe there is not, but we can turn back to Steve McConnell for a modern discussion with his 2019 book, More Effective Agile. More Effective Agile is the Rapid Development 2.0 for the agile-industrial complex, though we should note that the world is in a much better place when it comes to software delivery than it was in 1996. Now the question most people have is not “why do my software projects always fail”, but “why do my software projects always cost a bit more, or take a bit longer, than I would like”. Eventually many people end up with the question “why has all my forward progress ground to a halt in a mire of technical debt and defect fixing”, but often answers to those questions can be deferred for the successor CTO to answer.
In this context, McConnell revisits the central premise of Rapid Development: what does a software team need to succeed, are they getting it, and how can they get it? He describes Scrum as a good baseline framework for organisations transitioning to the agile approach, and “scrumbut” as a common reason for novice adopters to fail. Scrumbut is a hybrid methodology, where you treat Scrum as an a la carte selection of practices to pick and choose as you see fit. “We do scrum, but we have our daily standups once a fortnight”. “We do scrum, but our scrum master is also our engineering manager”.
Does this make McConnell a member of the brinksmanship school of the agile-industrial complex: if agile is not working for you, it is because you are not agiling hard enough? No, it makes him a realist: scrum is a framework for process improvement, but you can only succeed at improving your process once you have measured what is wrong with it and hypothesised how to fix it. If you are just starting out, stick in the shallow end of the pool and adopt the baseline process. One that is working for you and you are not going to drown, it is time to try changing things.
Just as agile itself jettisoned many of the agile practices from methodologies like XP, and Rapid Development borrowed from Fred Brooks the idea that there is “no silver bullet”, so More Effective Agile does not mandate specific technical practices. The two that are given decent space in the book are Continuous Integration and Continuous Delivery, both of which are still unevenly distributed throughout the industry so are good choices for an author who wants to make agile teams more effective.
Steve McConnell has been working in software and teaching software practitioners for over three decades, and there is still much to learn.
Cover image by Adrian Kosmaczewski.