IT'S MONDAY MORNING and a team is holding its weekly status meeting. Although they don’t know it, they're about to demonstrate three developer realities that managers often do not understand. Let's observe them in their natural habitat to see if we can learn anything.
Programmers Need To Fail To Succeed
Jay, one of the programmers, is the first to speak. He tells everyone he's behind in developing the new security subsystem. He spent last week investigating a third-party product that might have been a tremendous shortcut if it had worked. But, it didn't, and now he's a couple of days behind. Terry, the manager, her face red with anger, asks Jay why he spent time investigating a third party product when that wasn't on the schedule.
Terry Just Made A Mistake.
Often, on the path to a finished design or finished code, a programmer will take a detour through a flawed implementation. Managers often view these detours as mistakes; programmers view them as necessary steps toward the right solution. There is rarely one obvious solution to a programming assignment. To find the appropriate solution, programmers need the latitude to occasionally try solutions that do not work. When a solution doesn’t work, the programmer learns from the experience and tries the next solution that his knowledge and newly gained experience tell him is best. If the project is already behind schedule or if, as the project manager, you've become overly focused on marking tasks as complete on the schedule, this can be disconcerting.
A few years ago programmers even introduced a new word, refactoring, to refer to one type of detour through an unsatisfactory final solution. Refactoring refers to changing the structure but not the behavior of a piece of code. Programmers refactor when they have a piece of code working but do not like how the code is written or organized. By refactoring that code, they are often changing the underlying design (for example, introducing a class here or removing one there) but are creating code that will be more maintainable over the life of the project.
Programmers Like Challenges
During the status meeting, Terry questions Susan, another programmer, about why she's behind developing the five new screens. Susan acknowledges that she's behind but tells Terry that she's developing a user interface framework that will make it easier to develop all future screens. Susan says that, while she's behind now, she's confident that the new framework will help her catch up—as soon as she works out all the bugs.
Susan Just Demonstrated What Happens When Programmers Don't Feel Challenged.
Good programmers like challenging assignments. They enjoy being pushed to do something they haven't done before, to use a technology they haven't used before, or to do something better, faster, or smaller than anyone else has ever done. If a programmer isn't challenged by the assignment you give her, she will often find ways of making it challenging. Susan was assigned to write the user interface code for five new screens. But, instead of simply coding those screens, she coded a user interface framework that allows screens to be specified declaratively in an XML file. To test her framework and to deliver the screens, she wrote the XML file that defined the five new screens within her framework.
Of course, introducing a framework like this could be a good idea. The problem here, however, is that the decision to introduce the framework was made by one programmer and was introduced for the purpose of making her work more challenging and, therefore, more fun. This expansion of scope was only possible because the framework was arguably beneficial to the project in that programmer's mind. However, there was never any discussion about whether the development of this framework was the best use of development resources.
Sometimes a programmer will make an assignment more challenging by compressing the schedule. In this case, the programmer may have a week to do something she thinks won’t take more than two days. She may spend the first three days surfing the Web or reading up on some unrelated but intriguing technology. Only when there is the minimum amount of time left before the deadline will this programmer start on the assignment. This assignment is now challenging because it has to be done in a very short timeframe. This is much worse than making an assignment challenging by going way beyond the requirements, such as by developing a framework instead of coding the five screens. At least in that case, the team or customer benefits from having something they wouldn't otherwise have.
Development Is Not Done Sequentially
When it's his turn, Vadim says he's done with the analysis of what will be needed to comply with the Sarbanes-Oxley Act. Vadim points out that he’s finished analysis a day ahead of schedule but that he'll likely need the extra day for design. Vadim reminds everyone that a design review is scheduled for next Wednesday. Terry stresses that she wants everyone to come to that meeting prepared because she doesn't want Vadim to write a single line of code until the design is 100 percent complete.
Terry Is Making A Mistake In Assuming That Tasks Like Analysis And Design Can Be Completed Separately.
Despite the temptation to create a project plan that includes discrete items for analysis, design, and then coding, this is not how programmers work. Programmers do not work sequentially on anything but the most trivial tasks. Instead, programmers attack a problem opportunistically. They do a little design, then a little coding, then a little analysis, followed by a bit more design and so on. As whim and inspiration strike them, they move back and forth among these activities. We may put analysis, design, and coding tasks on a project plan. But, even when doing analysis, a programmer may think about the design and then about how to code the design.
In 1990 Raymonde Guindon confirmed this by studying a group of designers to whom she posed a problem. She happened to study elevator designers but the implications are equally relevant for software developers. Guindon paid particular attention to whether the designers were thinking top-down or bottom-up at any moment. Graphing how a particular designer thinks about a problem results in a chart like the one shown in Figure 1. The light bulbs indicate where a designer had an epiphany or breakthrough in her thinking. As you can see from Figure 1, designers (and programmers) move freely between top down and bottom-up thinking.
The implication is that we cannot have project plans that say a programmer finishes analysis on Tuesday, designs on Wednesday and Thursday, and codes for the next six days. A good programmer knows how she works and knows that these activities are all interspersed.
Six Things You Can Do
The status meeting concludes and all go back to their cubicles to continue these same behaviors. Is there anything that Terry (and managers like Terry) can do to get the most from these creatures called programmers?
Yes. Let's focus on six things you can do immediately to improve how you work with your programmers.
1. Encourage The Right Kind Of Failure
I've mentioned that programmers will occasionally pursue a wrong solution before discovering the right solution. You need to recognize the necessity of these types of failures and encourage your programmers in this. Famous inventor Thomas Edison once said, "I am not discouraged, because every wrong attempt discarded is another step forward." You would like your programmers to have this same mindset. When developers feel free to pursue possible dead-ends, they are likely to come up with their most innovative or breakthrough ideas. These are the times when a programmer comes up with an idea that turns a twenty-day task into a three-day task.
You do not want the programmers to become fearful that these necessary detours on the way to completing a task will be viewed by you as a waste of time. If that happens the programmers will either hide these activities from you (they'll still happen, you just won't be told about it) or they'll stop taking chances and thinking innovatively. In either case, the project will be the worse for it.
2. Discourage The Wrong Kind Of Success
In addition to encouraging the right kind of failure, it is equally important that you discourage the wrong kind of success. The wrong kind of success comes in two general varieties: doing the wrong thing and doing more than was needed.
Be careful of rewarding work on something that has not been agreed upon as a deliverable of the project (or of the current iteration of the project, if you're using an iterative process, which you hopefully are). If the work is truly beneficial, praise or reward the programmer to an appropriate extent but be sure she knows that, while you appreciate her enthusiasm and creativity, you need her to work only on the features that will be delivered as part of the project.
A more difficult situation to detect is when a programmer is doing more than is needed to meet a requirement. This is called "goldplating," and we often see it on projects where a programmer takes a relatively straightforward task and delivers along with it something like a fancy object hierarchy intended to meet a variety of future “needs." Since the future is hard, perhaps impossible, to predict, it's important to encourage programmers to keep their eyes on a project's most immediate needs. You need to encourage the programmer's commitment to the work that led her to go beyond the call of duty; but you also need to make sure she is working on the most pressing needs of the overall project.
Programmers are prone to doing more than necessary when the needs of the project are unclear. Recently I worked with a programmer who was asked to develop a series of extremely simple HTML pages. Each was to say something like "this is the search page" or "this is the results page" and provide appropriate links to other pages. This wireframe prototype was to be shown to users to verify that the workflow would be extremely easy for them. However, when the programmer completed the task, he had programmed the complete user interface with all visual components in place. His screen designs were wonderful but they were beyond what was needed. This problem could have been headed off with more and better upfront communication about exactly what was expected, followed by my checking in with him more often to view some of the screens before they were all completed.
3. Acknowledge The Unglamorous Tasks
Just as with your work, some programming tasks are exciting and some aren't. Each programmer has different criteria and different thresholds for what makes a task unexciting. For example, some programmers enjoy working on the user interface of an application; others consider it drudgery. When you present a task to the team, never sugarcoat it. If it's a boring or unchallenging task, just describe what needs to be done and acknowledge your awareness that the task is not a glamorous one. Similarly, if the task is politically necessary but otherwise unimportant, acknowledge this to the team.
If you try to generate artificial enthusiasm or assign false urgency to these tasks, you’re going to look bad. If a programmer knows that you know how mundane a task is, she will be more willing to get it done and expect that you’ll take care of her next time around. Having to work on an unglamorous task is one thing, having to pretend you like it is another.
Another partial solution to this problem is to have a good mix of programmers on the team. A task that may be unglamorous to an experienced programmer may be fresh and exciting to a less experienced developer. A broad mix of experience and skills is your best insurance for finding someone on the team interested in doing what some others would find mundane.
4. Explain The Why—So They Like The What
Programmers want to know the big picture; they want to know why specific tasks are necessary. Most of the time, the reason for a task is obvious. But, when it's not, go out of your way to explain why a task is important. When a team is told the reasons for pursuing a goal, it will often find better ways of achieving that goal. No one likes to be told to do something without being told why. This axiom holds true for small tactical work ("We need a password screen") as well as for strategic work ("We need to develop a stripped-down handheld version of our main product"). Most project managers do a good job of explaining the purpose of the tactical work but could improve at explaining the reasons for the strategy.
At one dot-com company where I worked, we were engaged in a rather fierce battle to stay ahead of our closest competitor. The two companies had gone public within weeks of each other, and it was important that our product contain all the features of their product and then some. Even the product managers were dubious of the value of some of the features but we knew our products were being compared side-by-side, and we didn't want to take the chance of not having a feature our competitor had. To make sure all of the developers were taking the competition seriously and understood the importance of winning, we held a couple of meetings profiling the other company. To ensure the point stuck, our presentations included photos of the competition's CTO, CEO, and CFO and gave each a humorous nickname. We later hung those photos around the office as reminders. By making the company's strategy—in this case, staying ahead of the competition—crystal clear, the developers could understand their day to day work within this broader context.
5. When It’s Vague, Say So
Not every task you’re going to assign will be well defined. No matter how thorough your requirements process is, members of your team will inevitably be required to work on some tasks that are not well understood. How you communicate these tasks is critical. If you ask someone to work on a poorly understood task but treat the task as well understood and assign it a deadline, the entire team—not just that programmer—is going to think you're entirely disconnected from reality.
Whenever you give a programmer a new task, you need to clearly communicate your expectations. If there's uncertainty around the task, say so. Discuss a realistic scope for the task and then continually demonstrate an awareness that it’s impossible to know how long something that isn't completely specified will take. Stay in touch with the programmer as long as she’s working on the task so that you can provide guidance about when to consider the task done.
To a programmer, there's not much worse than getting a vague assignment with a hard and fast deadline. If team members feel like you're aware of this, they'll tend to deliver more than if they think you are not. If they think you don't understand that vague tasks call for vague deadlines, they'll often do as little as possible to complete the task and hope to move on to something else as soon as possible.
6. Let The Team Own The Process
Regardless of the type of process you or your organization favors, the more the developers feel that they have contributed to and customized the process, the more they will support and follow it. The easiest and best way I've found to do this is to hold periodic project retrospectives that focus on what the team will start doing, stop doing, and continue to do. Hold these sessions perhaps once a month or perhaps at the end of each iteration or natural breakpoint in your projects. Focus on soliciting from team members answers about what they would like to start, stop, and continue. Make lists for each category.
For example, a team may want to start pair programming and writing automated tests for all new functionality. It may wish to continue working in month long iterations and holding end-of-iteration demos. Items on the continue list are usually ones that were recently on the start list. After awhile, when something becomes a habit, it can be dropped from the continue list. Until then, however, you may want to rewrite it on the list during each retrospective. The stop list is useful because it prevents the process from collecting crud over the years. Six months ago the team may have decided it wanted to run all user interface changes by a knowledgeable internal user. If that step is no longer adding value and is slowing development, it's a prime candidate for the stop list.
There are many ways you can conduct this meeting. For example, you can ask each developer to provide anonymous answers prior to the meeting; or you can go around the room asking each person to add one item to the list; or you can just have everyone yell out items at random.
I use Scrum, one of the Agile processes, on my projects but even if you use a waterfall process, the Unified Process, or something else, it is important for the developers to have some ownership over the process. No matter what process you've chosen, there should be some room for this type of customization to occur periodically.
As you become more aware of the development and developer realities that cause programmers and managers to approach situations from different perspectives, you will discover many more ways of improving how you work with the developers on your team. The six techniques here are only the beginning.
Guindon, Raymonde. "Designing the Design Process: Exploiting opportunistic thoughts." Human-Computer Interaction 5, 1990.