The following are best practices used in the creation of base processes for holonic software development. Many of these practices have become so commonplace in our industry that they are often overlooked or taken for granted, yet I feel it is worthwhile to list them here. Taken together, the ten best practices below comprise a development process that is:
-
Modular: Modularity is a key element of any good development process. A software development process prescribes a set of activities capable of transforming the vision of a software system into reality. Modularity allows the process to be broken into components called activities.
-
Iterative: Good development processes acknowledge that we get things wrong before we get them right; therefore, they focus on short cycles. Each cycle is an iteration of the development process. Within each cycle, a certain set of activities is completed,
generally within a matter of weeks. The iterative process recognizes that a single cycle is unlikely to result in complete success. Therefore, each short cycle is repeated many times to refine the deliverables.
-
Time-bound: Iterations become the perfect unit for planning the software development project. We can set time limits (between one and six weeks is normal) on each iteration and schedule them accordingly. Chances are that you won't schedule all the activities of a process into a single iteration (unless the process contains very few activities). Instead, you'll attempt only those activities necessary to achieve the goals set out at the beginning of
the iteration. Functionality may be reduced or activities may be rescheduled if they cannot be completed within the allotted time period.
-
Parsimonious: Creating impossible deadlines under a process not suited for rapid delivery puts the onus on the software development team. This leads to burn out and products of poor quality. Instead, a good software development process focuses on parsimony. That is, the process requires a minimal number of activities necessary to mitigate risks and achieve the set goals. Minimizing the number of activities allows the development team to deliver against an aggressive schedule while maintaining some semblance of a normal life (that is, sleeping at night).
-
Adaptive: During an iteration, new risks may be exposed that require the addition of new activities. The developer (or development team) adapts the process to attack these new risks. If the goal cannot be achieved using the activities planned during the iteration cycle, new activities can be added to reach the goal. Similarly, some activities may be discarded if the risks turn out to be ungrounded.
-
Incremental: A good development process does not attempt to build the entire system at once. Instead, we partition the nontrivial system into increments that may be developed in parallel, at different times, and at different rates. We unit test each increment independently. Upon completion and testing of the new increment, it is integrated into the system.
-
Convergent: Convergence states that we are actively attacking all of the risks worth attacking. As a result, the system comes closer to the reality that we seek with each iteration. As risks are being proactively attacked, the system is being delivered in increments. We are doing everything within our power to ensure success in the most rapid fashion.
-
People-oriented: Good processes favor people over process and technology. They evolve through adaptation in an organic manner. Developers that are empowered raise their productivity, quality, and performance.
-
Collaborative: Good processes foster communication among team members. Communication is a vital part of any software development project. When a project is developed in pieces, understanding how the pieces fit together is vital to creating the finished product. There is more to integration than simple communication, however. Quickly integrating a large project while increments are being developed in parallel requires collaboration.
- Balanced: Activities can be combined so that they complement each other. For example, writing user stories may be combined with writing acceptance tests (that is, concrete examples of the requirements depicted in the user stories) to ensure that the stories are testable. These activities work together in combination to prevent mistakes.