A development methodology is the overall style of how a project decides to organize the steps in developing the system. This includes decisions like whether to develop the system in increments of functionality, whether to design everything before building, whether to synchronize everyone’s efforts to a common cycle, and so on. These decisions are reflected in obvious ways in the life cycle patterns a project uses.
There are many methodologies named in the literature: waterfall, spiral, agile, and so on. Different sources interpret each of these differently, and they are rarely compared on a common basis. Some of these, like waterfall methodology, have evolved over time and do not have a single clear source or definition. Others, such as agile development, have a defining document (manifesto) to reference.
All of the methodologies I know of have come to be treated as dogma, and are more often caricatured than treated thoughtfully. This is unfortunate because each of the methodologies has something useful to offer, while all of them are harmful to project effectiveness if taken as dogma or used without thoughtful understanding.
These methodologies can be organized and compared based on a few characteristics. A project can choose a methodology with the characteristics it needs.
Size of design-build cycle. Methodologies like waterfall use “big design up front”, where the entire system is specified and designed before implementation begins. Other methodologies break up development into many specify-design-implement cycles.
The argument for doing as much design up front as possible is that errors are easier and cheaper to catch and correct before implementation than after. The arguments against are that in some complex systems the design work is exploratory and requires implementing part of the system to learn enough to know how to design—or not design—critical system parts.
Many iterative methodologies claim to be better at supporting adaptation as system purposes change.
Coupled or decoupled design-build. Some iterative methodologies plan to complete adding a feature to the system in one iteration, by executing an entire specify-design-build-integrate cycle for that feature. Other methodologies break up that cycle into multiple steps, and allow those steps to spread across multiple iterations.
Advance planning. Some methodologies emphasize planning out work activities as far as possible into the future, while others focus on planning as little as possible in order to adapt as needs change.
The argument for planning as far as possible into the future is that it gives the team stability: they have a reasonable expectation of what they should be working on now and have a sense of how that work will flow into other tasks soon after.
The argument for planning to shorter horizons is that someone will come along and change priorities or system purpose, and so the work will need to be changed to adapt. Planning too far ahead is wasted effort, it is argued, and gives teams a false sense of stability.
Regular release or integration. When a methodology uses many design-implement cycles, at the end of each cycle it can require that new implementations be integrated into a partially-working system, or it can go farther and require that the partially-developed system be releasable. Most iterative methodologies recognize that very early partial systems may not be releasable because they are too incomplete.
Regular release is feasible for products that are largely software, where a new release can be put into operation for low effort. It is less feasible for products that involve a large, complex hardware manufacturing step between development and putting a system into operation.
The choice of whether to release regularly or not is often dictated by the relationship with the customer(s) and whether the system is still being implemented the first time, or is in maintenance. Once the system has been deployed, development is likely either for fixes or for new features; these are often released and deployed as soon as possible.
Synchronization across project. Some methodologies that break up development into multiple iterations align all the work being done at one time so that the iterations begin and end together. Other iterative methodologies allow some work iterations to proceed on different timelines from other work.
Synchronizing work iterations across the whole project can provide common points to check that work is proceeding as it should and to share information about progress. However, it can also break up tasks that run far longer than others and result in a perception that the synchronization is wasteful management overhead rather than something useful.
Shared short-term purpose across project. Iterative methodologies can focus the entire team on one set of features across all the work going on at one time, or they can allow different streams of work to have different focuses in the short term.
The argument for this practice is that the more people share a common goal, the more they will be motivated to work together to meet that goal and to defer work that does not address that common goal. The argument for having multiple work streams with different focuses is that too often a project will involve work from different specialties and on different timelines: mechanically assembling an airframe and building a flight control algorithm have little in common.
I present three of the most commonly discussed development methodologies in order to illustrate how they can be characterized. Each of these methodologies has many variants, and all are the subjects of debates comparing tiny details of each variant. The purpose of this section is to illustrate how they can be analyzed, not to capture all nuances of every methodology in use.
| Waterfall characteristics | |
|---|---|
| Cycle size | One design-build cycle for the whole project |
| Coupled design-build | One cycle, so implicitly coupled |
| Planning | Plan as far as possible, especially after design |
| Release and integration | At end of project |
| Synchronization | n/a |
| Short-term purpose | n/a |
| Iterative and spiral characteristics | |
|---|---|
| Cycle size | One set of features crossing the whole system |
| Coupled design-build | Generally add to design and implementation for the feature(s) in the iteration |
| Planning | At the beginning of each iteration; variants maintain a roadmap of iterations or spirals |
| Release and integration | Either; every iteration ends with an integrated working system |
| Synchronization | All work synchronized to the iteration |
| Short-term purpose | Shared within the iteration |
| Agile characteristics | |
|---|---|
| Cycle size | One short iteration with many independent features and tasks, bounded in duration |
| Coupled design-build | Some agile practices focus on features, with a design-build cycle within one sprint to implement a feature. Other agile practices decouple designing, building, and verifying, allowing those to be spread over multiple iterations |
| Planning | At the beginning of each iteration; variants have a longer-term general plan |
| Release and integration | Either; every iteration ends with an integrated working system |
| Synchronization | All work synchronized to the iteration or sprint |
| Short-term purpose | Each task has its own purpose |
Waterfall development. This approach to development follows the major life cycle phases in sequential order. It begins with concept development, moves through specification to design, and only then begins implementation.
Waterfall development is well suited to building systems that have decision points that are difficult or expensive to reverse. The NASA project life cycle (Section 24.2.1) follows a waterfall-like sequence for its major phases because there are three decision points that do not allow for easy adjustment: getting government funding approval; building an expensive vehicle; and spacecraft launch.
This methodology can be inefficient when the system cannot be fully specified up front. When the system’s purpose changes mid-development, or when some early design decision proves to have been wrong, the methodology does not have support built in for how to respond. Projects using this kind of methodology are known to have difficulty sticking to schedules and costs that were developed early in the project, usually because some unexpected event happened that was not anticipated from the beginning.
In one spacecraft design project I worked on (Section 4.1), the team assembled a giant schedule for the whole project on a 20-foot-long whiteboard. This schedule detailed all the major tasks needed across the entire system. That schedule ended up requiring constant modification as the work progressed.
Waterfall development requires great care when building a system with significant technical unknowns. The serial nature of execution means that some important decisions must be made early on, when little information is available on which to base that decision. When those unknowns are understood, the project can put investigation or prototyping steps into the specification or design phases in order to gather information for making a good decision. On the other hand, if the team does not learn that some technical uncertainty exists until the project is into the implementation phase, the cost of correcting the problem can be higher than with other methodologies. In addition, the sequential nature of execution can create an incentive for a team to muddle through without really addressing the unknown, resulting in a system that does not work properly.
In the spacecraft design project I mentioned, there were technical problems with the ability for spacecraft to communicate with each other. These problems were not properly identified and investigated in the early phases of the project. As the team designed and implemented parts of the system, different people tried to find partial solutions in their own area of responsibility but the team over all continued to try to move ahead. In the end the problems were not solved and the spacecraft design was canceled.
Iterative and spiral development. This development methodology is characterized by building the system in increments. Each increment adds some amount of capability to the system, applying a specify-design-build-integrate cycle. Typically the whole team works together on that new capability.
Early increments in such a project often build a skeleton of the system. The skeleton includes simple versions of many components, along with the infrastructure needed to integrate and test them. Later increments add capabilities across many components to implement a system-wide feature.
Teams using iterative development often plan out their work at two levels: a detailed plan for the current iteration, and a general plan for the focus of the iterations that will follow.
This methodology provides builds in more flexibility to handle change than does the waterfall methodology.
Iterative development can be used to prioritize integration (Section 8.3.2), in order to detect and resolve problems with a system’s high-level structure as early as possible. This involves integration-first development, where the team focuses on determining whether the high-level system structure is good ahead of putting effort into implementing the details of the components involved.
Agile development. The agile methodologies—there are many variants—focus the team on time-limited increments, often called sprints. The approach is to maintain a list of potential features to build or tasks to perform (the backlog). At the beginning of a sprint, the team selects a set of features and tasks to do over the course of that sprint. By the end of the sprint, the features have been designed, implemented, verified, and integrated into the system. In other words, there is a life cycle pattern that applies to building each feature within a sprint.
Agile development aims to be as responsive to changes as possible. The start of each sprint is an opportunity to adjust the course of the project as problems are found or the team gets requests for changes. The agile methodologies arose from projects that were trying to keep the customer as involved as possible in development, so that the team’s work would stay grounded in customer needs and so that the customer could give feedback as their own understanding of their needs changed.
At their worst, the agile methodologies have been criticized for three things: an excess of meetings, drifting focus, and difficulty handling long-duration tasks. Note that these critiques come from people in teams who claim to be using agile methodologies, and reflect problems with the way teams implement agile approaches and not necessarily problems with the definition of the methodology itself.
Agile development emphasizes continuous communication within a team. In practice, this can lead to everyone on the team having multiple meetings each day: daily stand up meetings, sprint planning, sprint retrospectives, and so on. This likely comes from teams using meetings as the primary way to communicate, and from democratizing planning decisions that could be made the responsibility of fewer people.
Some agile projects have been characterized as behaving like a particle in Brownian motion: taking a random new direction in each iteration or sprint. This can happen when the team only looks at its backlog of needed tasks each iteration, or when new outside requests are given priority over continuing work. The focus on agility and constant re-evaluation of priorities can lead teams to this behavior, but it is not integral to the ideal of agile development. A team can develop a longer-term plan and use that plan as part of prioritizing work for each new sprint.
Finally, many complex systems projects involve long-running tasks that do not fit the relatively short timeline of sprints or iterations. Acquiring a component from an outside vendor or manufacturing a large, complex hardware component do not really fit the model of short increments.
Most projects actually choose to use a hybrid among the different methodologies. They may start from one of the generally available methodology definitions, but they adapt that template based on the needs of their project and their own experience. Projects often follow different methodological approaches for different parts of the work: the early work on stakeholders and purpose is often linear, with later work done iteratively, for example.
In practice, the projects I have seen that have been successful have applied common sense to the choices they make about how they chose the design methodology for their specific project.
I have several general recommendations for making the choices about what methodology to follow.
Beyond these general recommendations, which apply to any methodology a team might choose, I have three specific practices that I have found to be essential. These practices can be adopted in most methodologies one might choose. The are, first, focusing first on work that addresses areas of high uncertainty in the system; second, having shared milestones for many team members or the project as a whole; and third, explicitly managing reporting and communication.
Focus on uncertainty.
I have said earlier that focusing on areas of high uncertainty is a
useful heuristic for choosing what to work on. While this is partly a
matter for tasking decisions, not development methodology, choices in
the development methodology can make this approach more or less
effective.
There is a general way to look at the kinds of uncertainty discussed in Section 21.6. Uncertainty in one artifact is related to uncertainty in another. Consider an artifact B that derives somehow from artifact A. When the content in A is uncertain but B has been worked out, it is uncertain whether B will actually fit with A or not. For example, if a component’s design is built before its specification, then the design could end up being wrong and needing to be redone. On the other hand, if decisions have been made in A so that its uncertainty is low, then there it is uncertain whether B, which derives from A, is feasible. A component’s specification might require something impossible in that component’s design and implementation, for example. Similar situations arise for artifacts that are supposed to be consistent but do not derive from each other, such as the designs of two components that are expected to work together. In other words, it can be costly to make a decision in the absence of understanding the consequences of that decision.
At the same time, decisions have to get made. Artifacts have to get built and the system completed. The rationale for prioritizing work to reduce uncertainty is that it reduces the greatest uncertainty first and allows decisions to be made with more information than they might otherwise be. This should, more times than not, result in better decisions and thus less expensive rework later.
My approach to making progress while managing uncertainty is to work iteratively, exploring forward and backward informally through a set of dependent artifacts. This balances different kinds of uncertainty by trying out a decision in one artifact (such as specification) and thinking about its effects on a dependent artifact (such as design or implementation), and feeding information back to adjust the decisions so that implementations are feasible and components integrate down the line.
I have used a collection of techniques to work this way, generally with good success. I have used different names for different related techniques: iterative sketching, integration-first development, multi-horizon planning, and continuous integration and verification. These techniques work together, and can be incorporated into most development methodologies.
Iterative sketching responds to my own desire to wonder about consequences. When working on a component, or a set of components, I often wander through them, imagining how one part of one component might work. I sometimes mentally step through several components to follow how they react to some external event. All of this results in semi-organized, unofficial notes about all the pieces: notes on requirements and design approaches, on key implementation ideas, on what might be used to verify that a component or collection of them works. In process I come to understand what is needed and where the uncertainties are. What kinds of safety or security needs does the component have? What technologies could be used to implement it? The act of sketching also moves back and forth among artifacts, so that I can check on whether a specification or design approach is likely feasible, or adjusting a specification when I find that it leads some something unobtainable.
Sketching has two other benefits besides avoiding infeasible decisions. It uncovers technical uncertainties in upcoming work, and provides a basis for comparing the importance of one uncertainty against another. Better information about uncertainties helps guide decisions about where to put effort next. This approach also provides information to help development plans (Chapter 64).
With integration-first development, I have found that many costly problems come when components are integrated together for the first time. This reveals differences in assumptions and expectations in how the components were designed and implemented. The problems are revealed after a lot of detailed implementation work is complete, when the integration problems are costly to solve—and when it is more difficult to even detect integration problems. Instead, my teams have built simple mockups of components that have just enough functionality to interact with other mocked-up components, in order to verify that they can work together before building out the complex internals of each.
Multi-horizon planning (Chapter 67) practice of honestly acknowledging how much is known and how much is uncertain in the project at any given moment and managing work accordingly. It is a complement to the idea of focusing on uncertainty first by, in effect, tracking which uncertainties are being given priority and which are being deferred.
Finally, continuous integration and verification practices complement the practices developing artifacts iteratively. Continuous integration—in the original sense of continuously integrating separate components into a partially-working system—and then verifying the assembly helps find design and implementation problems as early as possible, reducing the cost of correcting the problems.
All of these techniques are examples of the principle of gradual stiffening [Alexander77, Pattern 208, p. 962]. This is a principle of building that places focus first on the large-scale organization of the system and then filling in details. One does this by “weaving” a system rather than building it in one pass.
It is helpful to imagine a building being made like a basket. A few strands are put in place. They are very flimsy. Other strands are woven in. Gradually the basket gets stiffer and stiffer. Its final structural strength is only reached from the cooperation of all the members, and is not reached until the building is completely finished.
Alexander advocates, in other words, working iteratively across a system, getting its broad structure in place and seeing that it works, and then filling in more parts bit by bit, checking that the details can fit into the big picture without disturbing it. The alternative of doing all the specification and design up front requires a lot of work early on to make sure it is right, without easy recourse when problems are found. In those situations, “the details of connections, and components, are allowed to control the plan” [Alexander77, p. 965].
This kind of practice addresses all the different kinds of uncertainty in a balanced way, so that addressing uncertainty about one artifact’s content does not create greater uncertainty about feasibility or integration in later artifacts.
These ideas of approaching work iteratively, making multiple passes over the artifacts for components, and planning to feed back information from dependent artifacts to earlier artifacts and from component to component all get encoded in the development methodology. Agile and Spiral do not address these principles directly, though they leave room for them. This practice can be added to a basic iterative development framework.
Shared milestones. In a project to build a complex system, it is too easy for some team members to focus on their particular components and to lack incentive to consider the larger system. This can lead to people building artifacts that do not integrate together into a coherent, working system.
Giving groups some kind of shared objective, where they are all responsible for not just their own piece but for the working integration of the pieces, can help mitigate this tendency. A shared objective can foster a sense of working together, and as I will discuss next, doing so can help communication within the team.
In many projects, I have created artificial milestones where the team, or a part of it, would demonstrate some significant increment of the system working. In one project, the funder expected a series of demonstrations and reviews to check that the project was on track. In another project, I created milestones that took a month or two to reach. In each case the team worked together to reach those goals. The goals helped them focus on the work at hand, and made it easier to accept that they did not have to build a complete and perfect version of each component all at one time. The teams also had reason to celebrate their progress at each of these milestones; they were used as an opportunity for public recognition of their work.
Most projects also have hard decision points, often externally imposed, when decisions will be made whether to continue the project or not. Examples include the decision to award the team a contract to build the system, or decisions to continue funding. These decision points impose a degree of waterfall-like structure on the work. For example, one project had to present a proposal to a government agency in order to get a contract to perform detail design and prototype implementation. That proposal involved developing the concept for the system, showing how it met the customer’s objectives, and showing that there was a likely feasible design. (Once the contract was awarded, the team used a spiral development methodology.)
The choices made for development methodology can help or hinder this way of working. Methodologies that support developing components iteratively make it easier to divide the work of a complex component (such as a large subsystem) into steps that can be demonstrated and celebrated.
Managed communication. Many projects that have attempted to follow an Agile methodology report “death by meetings”: constant team meetings where most people don’t have much to say for most of the time, but the meetings eat up a lot of hours and create constant interruptions. This effect is the result of bad management, not of an Agile methodology per se. It arises when the team, or its leaders, avoid making decisions about how reporting and communication can be done effectively and instead default to group meetings to broadcast lots of information to people who mostly don’t need to know.
Much communication happens best organically, when people talk while they work together. A small group that is working together can set up ad hoc communications if needed. When a group is working together but is not located together, then short daily status meetings can be appropriate—but they should not replace continuous informal communication within the group.
Ordinary communication outside the small working group falls into three categories: information that is shared between these small working groups; reporting for management tracking; and top-down communication shared to parts of the team. These can be achieved by assigning some people in each group the responsibility to keep other groups up to date, and to share information the receive from other groups with their team. Other people in management roles have responsibility to collect status information by listening to how each team is doing and sharing that to others who may need the information. (This is the idea of managing by walking around (MBWA) [Packard95, Chapter 11].) Finally, when information needs to be presented top-down, those responsible can involve only those people affected (though that might be everyone on the team sometimes).
At the same time, every project I have worked on has had some kind of regular meeting. Regular meetings help people on the team keep in touch with everyone else, avoiding situations where part of the team gets forgotten because they aren’t interacting with others enough. These regular meetings should have an explicit social purpose and be organized to promote social cohesion, not dressed up as having technical objectives.
These choices, which I discuss more in Chapter 58, are independent of the choice of methodology. Making a choice of methodology does not force one into a choice of communication style.