Many companies in the U.S., Europe, and Japan are now building or contracting for new software products, components, and custom-designed systems that will be created in globally distributed teams, such as in India or China, and increasingly in Russia, Eastern Europe, Southeast Asia, and Latin America. While taking advantage of lower costs and broader talent pools around the world, the problem with this trend is that the world is not exactly "flat," as Thomas Friedman of the New York Times has asserted. Many companies send programming, engineering, and technical back-office work overseas and get excellent results. But software development can be tricky in many circumstances, which is why globally distributed teams require special skills in system design and project management.1
One of the biggest challenges is to apply an iterative (or more popularly called "agile") style of development when teams are large and not co-located. This is important because a lot of the research over the past decade on software engineering and product development in general has concluded that iterative approaches have lots of benefits, in contrast to traditional waterfall or sequential methods of developing new products. Iterative techniques make it possible for projects to respond more easily and, while they are in progress, to changing demands from customers or unforeseen challenges from competitors.2 Iterative software engineering practices range from the daily builds and milestone approaches of firms like Microsoft to the more nontraditional practices of extreme programming (see my October 2007 column). We also know that, as long as projects do things like show early prototypes to customers, run regression and integration tests on each of their builds, and do frequent design reviews, they can accommodate a lot of change while still keeping quality and budgets under control .
But these and other iterative techniques become more difficult to use consistently when teams are geographically distributed in different countries and cultures around the world. On the technical side, we often see unclear or too rapidly changing requirements, delays, and mistakes in shifting from design to implementation, unforeseen technical interdependencies that thwart integration of components, and bug-ridden code caused by these and other problems. On the organizational side, there are varying communications, as well as development, styles in different countries, as well as differing degrees of facility with the English language. In response, many companies resort to sequential waterfall-like planning and project management when they distribute software or other engineering work globally under the assumption this is a simpler way to deal with communication and coordination problems. This may be true sometimes, such as in embedded software development projects where specifications need to be tightly fixed. But if companies want to maximize their ability to respond to customer needs and changing market conditions, they still need to figure out how to incorporate iterative development techniques.
Managing global teams is common today but is not a new problem. IBM, for example, developed OS/360 in the 1960s and successor operating systems in multiple sites around the U.S. and Europe. Today, though, it seems that Indian software firms, led by Infosys, Tata, Wipro, Satym, and a few others, have taken the lead in refining a "global delivery model."3
The best practices I am familiar with begin with an iterative process, adopt waterfall-like practices in the middle implementation phase, and then move back to iterative to complete the project. They work roughly as follows: The software provider (such as an Indian IT services vendor or perhaps Accenture or IBM Global Services) sets up a project office at or near the customer site. Experienced requirements engineers and project leads work closely with the customer to generate a scoping document, preliminary requirements, and even prototypes of part of the product or system functionality.
The next step is to produce more detailed requirements for critical parts of the system, as well as a preliminary development plan and budget. Later, the team based in India (or China or Russia) will do detailed design, coding, unit testing, integration, and system testing—not usually in one phase but in a series of milestones or subprojects representing major parts of the system or components being built. Eventually, the team will bring the completed system back to the customer for final acceptance testing and start iterating again to get the final details right. They should know where they are in the project if the development team has been working with the customer closely all along.
But before a software company can make these handoffs and handbacks work relatively smoothly, the globally distributed team must have several basic elements in place.
First, and perhaps the most difficult, is to create an iterative contract with the customer—if possible. Customers often want a fixed price and schedule, especially when they are dealing with low-cost suppliers competing for their business. But, for the software provider, too many things can still go wrong in any large project, and it is easy to lose money on fixed-price contracts if the work spins out of control or if the initial estimating was poorly conducted. One strategy is to persuade the customer to agree to an initial scoping and prototyping engagement lasting from a few days to a few weeks, depending on the size or complexity of the task. After that effort, the software provider should be able to offer a more precise estimate of the cost and time required for the project. Most contracts will then require the customer to pay for the work incrementally as the software is built. But exactly how much to pay could be determined as the work is planned in more detail and as the customers learn more about exactly what they want.
It is essential to do frequent updates with the customer on the state of the project—show the customer each week what the team is doing, how far they have progressed versus the schedule milestone, and what the evolving product or system actually looks like. It is critical to keep iterating back and forth between the customer and the developers offshore rather than simply attempt a one-time handoff. No one gets it right the first time. But it is equally important to put some time limits on the changes and move forward in discrete milestones or subprojects so the iterations are not endless.
For these steps to work well, it is essential to break up the system into clearly defined subsystems, components, or increments that separate teams working in parallel can design, build, and test as independent modules, at least to some degree. Each increment also should take no more than a couple of weeks to complete and then integrate with other parts of the system under development; otherwise misunderstandings between the requirements engineers and the programmers and testers will persist and grow. This kind of decomposition or architectural design is easier said than done. It requires considerable thought and planning up front in a project, as well as a deep domain understanding of the type of system or product the customer wants developed. But, with adequate modularity, a distributed project team can have several small groups work independently; they can accommodate frequent changes and later bring their work together—more or less successfully.
In order to keep teams synchronized, the project managers must do what all good iterative projects do, whether they are located in one site or in a dozen—employ short design, build, and test cycles of a couple of days or weeks at the most. Then the team members need to review their designs and code frequently, as well as test their builds with other components from other sites, as often as possible. Some distributed teams prefer to work with what are really mini-waterfall cycles of, say, a week or two and then do their reviews, integration, stabilization (bug fixing), and system testing work intensively for each cycle. Whatever the scheduling, the key is to keep the teams synchronized and the components as de-coupled or as modular as possible to reduce interdependencies and integration "gridlock," also known as "infinite defect loops."
Globally distributed projects must involve participants with strong organizational and process skills. It is generally very useful to have a strong project manager leading the entire effort, to have a commonly accepted development process (such as an iterative version of CMM), and to have occasions for the team members to meet each other and communicate directly to solve major issues that might occur.
It is useful to have tools that support distributed development and large teams. Today, there are many in-house and commercial tools available to facilitate daily builds, continuous regression and integration testing, and version control, as well as configuration management. Distributed teams also rely on email and videoconferencing to communicate. With high-speed data connections, the tools that work for a co-located project also can work for a globally distributed project.
We have advanced far beyond the days when IBM engineers would travel the world carrying reels of magnetic tape whenever they wanted to do a system build for pieces of software made in different locations. So, yes, with the Internet, we can distribute work globally in a way never before possible or economical. But our thinking and management skills still need to catch up with the technology and global realities. The world is flatter than it once was, but when it comes to software development, there are still many potential bumps in the road. Fortunately, we generally know where the bumps are located.