A process is a continuous series of activities that convey you to an end. Most software engineering textbooks and software developers list four main activities in a software development process (subsequent to the completion of systems engineering and prior to the first deployment):
Maintenance begins after deployment with a focus on bug repairs and enhancements. Maintenance usually involves further analysis, design, implementation, and testing. Among the testing activities during maintenance is regression testing, which ensures that successful test results after changes are the same as those before changes.
These activities can be refined into more specific tasks. Analysis sometimes is decomposed into domain analysis, whose focus is in understanding the problem in a more general context, and application analysis, whose focus is in understanding the specific problem to be solved in design. Design encompasses architectural design, subsystem and package design, class design, and algorithm design. Implementation includes class implementation and integration. Testing includes checking the basic units, integrated units, subsystems, and systems.
Many software development projects follow an evolutionary process model an incremental model, a spiral model, or concurrent engineering. We will focus on an incremental process model.
Under an incremental development process, a system is developed as a sequence of increments. An increment is a deliverable, including models, documentation, and code, which provides some of the functionality required for the system. The products developed in one increment feed into the development of the next increment. Successive increments add (and sometimes change) system functionality. The final increment delivers a deployable system that meets all requirements. Increments can be developed in sequence or one or more can be developed concurrently.
To build each increment, developers analyze, design, code, and test as needed. They typically have to perform these activities repeatedly in building an increment because they find errors in previous work. As development progresses, they gain new insights into the problem and the solution. We prefer to acknowledge this iterative aspect of incremental development and make it part of the process. We refer to this as an incremental, iterative process. In planning each increment, we include explicit steps for repeating various activities. Among these are steps for systematically reviewing current models, identifying errors based on experiences in later tasks, and modifying the models (or code) that have already been produced not just those that will be produced in the future. Figure 3.1 illustrates the process when the increments are planned sequentially.
Figure 3.1. A simplified sequential, incremental, iterative development process
Object-oriented development is particularly well suited to evolutionary development because object-oriented analysis, design, and implementation entail the successive refinement of a single model. This is the case both within an increment and among increments. In object-oriented analysis, we understand a problem by modeling it in terms of objects and classes of objects, their relationships and responsibilities. In object-oriented design, we solve the problem by manipulating those same objects and relationships identified in analysis and introducing solution-specific classes, objects, relationships, and responsibilities. Implementation is straightforward from a well-specified set of design products. Thus, the entire development process involves a refinement of a model. Design products are primarily an extension of analysis products and implementation products are coded expressions of design products. The products of one increment are extended and refined in the next increment. This is also a strength of the paradigm with respect to testing because we can utilize refinements of the same test cases in testing refined models.
The incremental development of products requires the incremental testing of those products. Products can change from increment to increment in both planned and unplanned ways. Test suites must change in concert. Regression tests must be run between increments and within iterations to ensure that changes do not adversely affect correctly working code. A process in which work on one increment overlaps work on another adds to the complexity of development and testing. Coordination is required to sequence the development of interacting increments so that objects that are associated with, but assigned to different increments, can be tested in a timely fashion.
The development of Brickles followed a plan based on an incremental, iterative development process. Our initial plan is outlined in Figure 3.2. When we started, we understood the requirements quite well, but we had no experience developing applications with the Microsoft Foundation Classes (MFC), nor did we have any experience developing arcade games. We recognized those as the biggest risks to success and planned to address those issues first. We also planned to test as much as we could as work progressed, which means we tested products within and/or at the end of each iteration. This is not shown in the figure.
Figure 3.2. Outline of our incremental, iterative development plan for Brickles.
There were significantly more informal iterations than those listed in Figure 3.2. This was particularly true during design, where we found that a number of decisions about scope and behavior had not been made during analysis.