Coming up to speed on an existing project is always a challenge, and coming up to speed on a troubled project can be a real conundrum. Tolstoy said that “Happy families are all alike; every unhappy family is unhappy in its own way.” The opposite holds true of software teams.
A troubled project, almost by definition, has overcommitted resources with little time to work through issues that, universally, were either underestimated or entirely unforeseen. The compromised system that is being negotiated (or, more likely, that will be presented as a series of fait accompli) is poorly documented and has large amounts of scaffolding, whose deployment is ad hoc or at least non-automated.
Even if management coughs up the money for new resources—bringing in consultants or hiring new developers—they invariably face the conundrum of coming up to speed. The developers with the best sense of the system are under great pressure to be heads-down and the entire team is so immersed in the project, that they have a difficult time explaining the context and the shifting of abstraction levels needed to comprehending a system. “Yeah, but there’s a problem with that…” they are likely to say to a new developer’s tentative understanding of the project.
Another problem, real but overemphasized, is tool and library use. This template engine, that unit-testing solution, this database, that language level, etc. Here, the devil is in the details: downloads, licenses, patches, environment variables, integration—all the things that are necessary to get to “Hello, Trouble System!”
Of course, there’s also the real possibility that the newcomer will be new to the tool or library, which will additionally slow things down, but not so much as is often feared. (If the new developer is reasonably talented and the tool or library is reasonably worthwhile, the developer will get it quickly enough and, in an existing project, will generally have enough examples to muddle forward, albeit inefficiently.)
Organizationally, heads are likely to have rolled, key programmers have likely slammed the doors behind them on the way out, and the consultant or new hire is wise not to become too attached to the people he meets on Day One. (Or even before; I once was crossing the parking lot to check in for my first day of work, and the fellow to whom I was to report pulled up in his car, shook my hand, told me he’d been fired, wished me luck, and drove off.)
That key programmer is always part of the equation. I don’t believe in super-programmers, but in every codebase, there’s some “Kilroy was here” fellow whose fingerprints are everywhere in the critical routines and “Why this, not that?” design decisions. I think there’s a Kilroy in all projects, whether troubled or not, but Kilroy moving on is often the source of baroque implementation issues; the sudden loss of a unifying vision (or at least perspective) can lead to code that is “inspired by” the original and misses the point as completely as a Hollywood sequel. Correctly divvying the codebase into the routine, crucially unique and pointlessly complex is one of the harder challenges for the new developer.
What else can we say with some confidence about our troubled team? Regrettably, we can predict that there is mutual distrust between management and the development team. By far the most common trigger for the bringing in of new resources is a deadline that was not only missed, but blown. Often enough, there’s an application that, while undoubtedly a failure in the opinion of the users, is pointed to by the developers as evidence of their dedication to directions they had been given (and which, we can predict, were changed in myriad ways as the months went by).
How does one quickly comprehend a system? Now is a time when the diagrams of the UML are at their most helpful; one can be skeptical of the value of modeling on a day-to-day basis, but there can be little doubt that UML diagrams provide a lingua franca for describing several aspects of an object-oriented software system.
While UML’s “flagship” class structure diagrams are less and less helpful in these days of dynamic languages, dependency injection, opinionated frameworks and functional languages, diagrams for use cases, sequences, and package relationships and deployments are easy to draw, read and, if the conversation calls for it, are capable of semantic precision that can produce a crucial “Ah ha!” of understanding (if not, sadly, reliably lead to the hoped-for “Eureka!”).
With a basic understanding in hand, how does one begin making contributions? Preferably the same way one works continually: One gets a clean build running, finds an item in the backlog that is small enough to be confidently committed to, writes a test that breaks, and begins the cycle of fixing, refactoring and moving forward.
But one does not expect to find a committed-to agile development process when one encounters a troubled team. Trouble is possible in any team, of course, but agile adoption is still rare enough that finding it in place is a surprise. And while I’m sure there are some developers who feel incremental test-driven development has been forced upon them and stands in their way, I’ve never met any.
Brooks’ Law (laid out 35 years ago!): “Adding manpower to a late software project makes it later.” A developer entering a troubled project faces the other side of the coin: “Joining a troubled software project is a troublesome affair.”
Larry O’Brien is a technology consultant, analyst and writer. Read his blog at www.knowing.net.