Saturday, October 4, 2008

The programmer life cycle

Legendary Canadian businessman Jimmy Pattison was famous for his ruthless policy of firing the poorest performing monthly salesperson at each of his many car dealerships. I could never do that at my own company – Backstage Technologies, a casual game studio and sometimes contract software engineering firm – because excellent programmers like the guys who work for me are extremely difficult to replace. But that doesn’t mean I don’t rule with an iron fist. In fact, I think there should be a Japanese-style TV reality show set at Backstage entitled Iron Fist. Each weekly episode of Iron Fist would conclude with me, adorned in iron gloves, whaling on the nuts of the employee with the fewest accumulated lines of code in production. Unfortunately, most weeks that would be me.

Why is my productivity waning, and why isn’t the amount of work that my employees do constant? Most textbooks on software engineering make at least passing reference to the notion of programmer productivity. The conventional wisdom is that an average programmer completes a paltry 500 debugged lines of code (LOC) per month. To students and professionals alike, this number seems absurdly low. The standard set of explanations for this phenomenon includes, among other things, the communication overhead of working in teams (i.e., Brooks’ Law), and the time allotted to non-programming activities like requirements gathering, documentation, and design.

These explanations tell only part of the story. While it has long been accepted that productivity rates can differ by an order of magnitude between the best and worst programmers, little has been said regarding the reality that work rates of the same programmer can likewise differ over time. Not unlike the software systems they construct, programmers follow a predictable life cycle. However, the programmer life cycle is not comprised of distinct activities (like the software development life cycle, which we discuss below) but rather by emotional stages that directly affect and predict productivity. The sequence of stages is characterized by an initial six month period of intense interest, at which time productivity rates are indeed much higher than the oft-quoted 500 LOC/month average. After a short period of volatility, the programmer then enters a prolonged phase of steadily dwindling interest, resulting in productivity rates that mimic the average. Each time a programmer switches employers or begins a significantly new project, the life cycle starts anew.

This conjecture is based purely on my experiences and observations while working as the senior software engineer for two successful Internet startups (abebooks.com in Canada, then Prophet.Net in the United States). The basic premise of the proposed relationship between stages of the programmer life cycle and productivity is the simple observation that employees are most productive when interest and satisfaction in their jobs is at its highest.

The Software Development Life Cycle
According to Webster, a life cycle is the series of stages through which something (as an individual, culture, or manufactured product) passes during its lifetime. In the case of a software product, the usual stages of its life are: requirements, design, implementation, testing, and maintenance.

Briefly, the requirements stage is when the product is conceptualized as a set of requirements, which are documented by a business analyst. This is what the product must do. The design stage is when a software architect imagines how the software will be built by decomposing the system into a set of interacting subsystems (database server, application server, web server, etc.), which in turn are decomposed into their constituent modules (database tables, transactions, stored procedures, classes, processes, threads, etc.). The architecture of the system is usually described by a set of directed graphs, where the nodes are the subsystems and the arcs denote relationships (e.g., “calls”, “stores”, “reads”). This is how the product will work. The implementation stage consists of database administrators and programmers realizing the design as a working program. The testing stage is meant to ensure that the program meets the requirements. Once this has been determined, a version of the program is released to its user community. Finally, the maintenance stage is where the program is changed into new releases that fix bugs that were not discovered during the testing stage, and new versions that add additional features.


Figure 1. The waterfall model of the software development life cycle.

Part of the goal of software engineering is to apply what is known as engineering rigor to the process of programming, the belief being that if it’s good for building bridges and toaster ovens, it should work just as well when writing software. Since engineers love linear project plans that involve milestones in the form of diagrams and documents, the first attempts at applying this concept to software development led to the infamous waterfall model of the software development life cycle. The waterfall model (see Figure 1) imagines each of the five stages of the life cycle as a self-contained step, where the output of each step falls only into the next. The model does not allow for backtracking or for information to flow in any direction but down. The obvious analogy to shit rolling downhill is left as an exercise to the reader.

The Stages of the Programmer Life Cycle
Everything we do as software engineers falls under one of these five categories that comprise the software development life cycle. The effectiveness with which we undertake these tasks is governed by where we are in the programmer life cycle (see Figure 2).

The programmer life cycle is comprised of six stages:
  1. Euphoric
  2. Productive
  3. Irreplaceable
  4. Resentful
  5. Bored, and
  6. Unproductive
While this particular life cycle model is perhaps most likely to apply to highly productive individuals (so-called star programmers) working in the 24/7 world of web development and e-commerce, it is my belief that there are fundamental truths in its structure that render it applicable to many software development situations and domains.

Euphoric. The first stage involves the start of a new job or significantly different project. The programmer is stimulated by both the newness of the environment and the challenges ahead. In many cases the programmer’s euphoria is fueled not only by these changes, but also by the coincident escape from a previous work situation that had become routine or was underutilizing his/her talents. This introductory phase is quite short in duration, lasting only as long as necessary to acclimatize to the new surroundings, learn a new development environment, and become familiar with the domain.

Productive. Once acclimatized, the programmer’s work interest reaches a peak. Because of this acute interest, productivity is at its highest. This stage – which lasts about six months – is when the programmer develops or takes ownership of some mission-critical software system. This coincides with steadily rising value to the organization.


Figure 2. Productivity as a function of stages of the programmer life cycle.

These first two stages constitute the “honeymoon period.” The next two are best described as the “volatility phase.”

Irreplaceable. Management soon recognizes that the programmer has become a valuable commodity. The programmer’s prestige within the organization is at an all-time high. As such, significant increases in compensation and fringe benefits are doled out in an effort to keep the programmer from ever possibly consider leaving. The golden handcuffs are sealed with the ubiquitous stock option grant, or the promise of one. The programmer feels on top of the world. Unfortunately this will not last.

Resentful. Management – sensing a sudden asymmetry in the employer-employee relationship – begins to bear resentment that a single individual (the programmer) is now responsible for the ongoing success or failure of the venture. Fearing a loss of control, management begins to act in a manner suggesting ownership of the programmer’s time and space. Symptoms of this malaise include requiring the programmer to carry a pager, work weekends, install broadband connectivity at home, and never under any circumstances take holidays. The programmer starts to receive email at all hours of the day from trigger-happy monitoring software reporting false alarms, and from managers requesting new features and emergency bug fixes.

In return, the programmer develops feelings of resentment towards management. This is exacerbated by management’s policy of rewarding the programmer’s competency not with bonuses and time off, but with additional workload and responsibilities. The first signs of complacency begin to appear in the programmer’s workplace attitude.

This unstable time of mutual resentment is necessarily short-lived, as emotions run too high for the process to carry on for more than a month or two. The working relationship can implode during the resentful stage, particularly if volatile personalities are involved. In the worst case, the programmer quits; the additional workload coupled with the stress of being irreplaceable yet resented becomes too much to take. However, in most cases the resentful stage merely settles into an equilibrium of mutual need: management’s need for the star to carry on keeping the software running, and the programmer’s need to be a star.

Bored. The post-resentment equilibrium sees the programmer’s activities shift more towards ongoing maintenance, consultative meetings with management, and internal knowledge transfer to other programmers and customer support staff. Because the initial challenges of the new project, environment, and technologies have all been met, the intellectual stimulation has dropped. This leads to boredom. Coupled with the excessive mental context switching demanded of the new activities, the programmer’s productivity (as measured by LOC/month) experiences a significant drop. Despite the tedium, however, this stage can last indefinitely provided the productivity remains above the minimum expectation level given the programmer’s current remuneration.

Unproductive. Like a manic depressive who goes off his medicine because he misses the occasional euphoric episode, or a love junkie addicted to the adrenaline rush of the first six months of a new relationship, the programmer is unlikely to remain in a state of boredom forever: something has to give. The change is triggered by a slide into the unproductive stage, characterized by the programmer working on his/her resume and visiting job sites on the ‘Net, while management views the programmer as “coasting,” overpriced, and expendable. One of two outcomes is inevitable: the programmer finds a new employer, or management moves the programmer to a significantly new role or project. Either way, the life cycle starts again.

Conclusion
This life cycle model should serve as a cautionary tale to both programmers and managers. The lesson for the programmer is to be aware of each stage and its effect on productivity levels, for ultimately one’s success as a software engineer depends on one’s perceived productivity. By recognizing the symptoms of boredom leading to unproductiveness, the programmer can proactively search for remedies, usually in the form of a frank discussion with management, or seeking out new projects and technological challenges.

Conversely, managers must understand the causes and effects of this life cycle in order to combat high levels of attrition and declining productivity. To get the most out of the organization’s stars, managers must avoid the resentment trap by resisting the temptation to over-burden the irreplaceable programmers with additional responsibilities lest they kill the golden goose. Instead, managers should look for challenges that will keep the stars at their peak performance level.

END NOTES

The waterfall model is due to Winston Royce, “Managing the Development of Large Software Systems,” Proceedings of IEEE WESCON 26, 1970, pp. 1-9. Ironically, Royce proposed the waterfall as an example of how not to build software systems.

Brooks’ Law, which states that adding manpower to a late software project only serves to make it later, is from Fred Brooks Jr., The Mythical Man-Month: Essays on Software Engineering, Addison-Wesley, 1975.

The first study to find significant differences in programmer productivity is Sackman, H. H., W. J. Erikson, and E. E. Grant, “Exploratory experimental studies comparing online and offline programming performance,” Communications of the ACM, 11 (1), 1968, pp. 3-11. Brooks himself estimates that good programmers are 5 – 10 times more productive than ordinary ones.

The 500 lines of code per month average is cited in Van Vliet, H., Software Engineering Principles and Practice (Second Edition), John Wiley & Sons, 2000, p. 175.

An earlier version of this essay appeared in Software Engineering Notes, volume 29, number 3, 2004.

0 comments: