Jason Hyman's Homepage

Chapter 2: Software Process Model

Software Lifecycle and Lifecycle Models

Adopting an engineering approach to the production and maintenance of software implies taking a holistic view of software development. The importance of software development as a whole, as well as the importance of the interdependence of its parts, is emphasized. The focus of software development is no longer exclusively on programming.

A software system has a lifecycle. Its lifecycle extends from the time at which the idea of having such a system was initially conceived and continuing until the system is no longer needed. In defining the lifecycle, all activities occurring during this lifecycle must be addressed. The techniques described are derived from some view, or model, of the lifecycle of a software system.

A more deliberate and engineering-like approach to developing software implies that some defined process is being followed. A process is a set of procedures, organized so that a product can be built that satisfies certain goals or standards. A software engineering view of the software lifecycle implies the conscious planning of software projects according to a software process, which then defines the approach being followed. These software processes are described with a software process model.

The Process Model

The software process model described herein is an extension of a well-known model known as the waterfall model. Here, the process model is examined at a very high level, briefly examining each phase.

The phases in the process model are defined by related activities and documented through production of phase artifacts. The progression of the phases leads to systematic development of the software system. It is important to note that the activities of one phase are highly dependent upon the activities from the previous phase. Therefore, it is crucial to perform the activities of one phase completely and as accurately as possible while in the phase before proceeding to the next phase. Errors and incompleteness in an early phase, which carries forth to following phases, are therefore the costliest to fix.

An often overlooked, and yet crucial part of each phase, is production of an artifact of the phase. This artifact serves to document the activities of the phase. Documenting activities of a phase provides a two-fold advantage. First, it requires that participants in the phase clearly express what goals are being set, how they are proceeding to meet those goals, and the outcomes whether successful or not. Secondly, phase documentation provides a reference for the project team and helps to soften the effect of team member acquisitions and departures. New team members may use the documentation as a roadmap in unfamiliar territory.

The architecture of the process model can be diagrammed as follows:

Figure 1: Process Model

This process model describes software development divided into ten phases. Please note that there are three major groupings: Preliminaries, Initial Development, and Maintenance. The Preliminaries consist of three phases: Personnel Identification, Requirements Definition, and the Go/No Go Decision. Initial Development consists of six phases: Requirements Specification, System Test Planning, Design Specification, Implementation and Unit Testing, System Testing, and Delivery. Maintenance consists of seven phases: Maintenance, Requirements Specification, System Test Planning, Design Specification, Implementation and Unit Testing, System Testing, and Delivery. The phases of Requirements Specification through Delivery consist of similar activities during Initial Development and Maintenance; however, they do have their differences as the activities stem from Maintenance instead of Initial Development.

Personnel Identification

As the need arises for a software system to be developed, a project team needs to be assembled on the developer end and a client team on the client end. The project team may not have the authority to impose roles on the client, but they should be able to adapt client personnel into roles definable by the developers.

The developers should define roles both for themselves as well as the client, adapting as necessary for the client. The roles should be defined around major decision categories. For example, a role should be defined for leading the sub-team responsible for developing the business rules. Another role should be defined for leading the designers of the system. A typical role for the client could be something such as the lead for testing the delivered product.

While the roles should be clearly defined, there is not necessarily a one-to-one relationship between role and the one who fills the role. Several personnel may take on a role and a single person may take on several roles. Therefore, the relationship can be many-to-many.

As stated before, each phase has an artifact documenting the activities of the corresponding phase. As the activities of this phase are defining roles and assigning personnel to those roles, the artifact for this phase is an organizational chart describing those decisions. The artifact is important as it provides a quick reference for the project team as to who should be approached with a specific type of question.

As the project team is assembled and the organizational chart reflects that assembly, it is time to start eliciting from the client exactly what is needed from the system. In this model, there are two phases of requirements gathering. The approach is one of deduction: we first examine requirements at a high-level, obtaining requirements in general terms, and then proceeding to more specifics. The first, high-level requirements gathering aims to define the requirements, and is appropriately titled Requirements Definition.

Requirements Definition

The activities of this phase are marked by the characteristic of gathering requirements from the client at a high-level. This first phase is a part of the classic requirements analysis of software engineering. It is here that we are trying to identify the problem, not the solution. Both requirements phases aim to gather the capabilities or services which the system much provide as well as the constraints under which the system must operate. The difference is the level of detail called for.

Requirements Definition can be characterized by this high-level, initial approach to gathering requirements. Its aim is not to capture specific instances of what is required, but rather notions of what is required. For example, if a system were being developed for a video inventory system, at this stage we would not be worried about specific scenarios such as adding, modifying, and deleting videotape. Rather, we would be concentrating of the fact that the system must provide videotape management capabilities in addition to other capabilities such as reporting and exporting.

This phase is characterized by three sub-phases. The three sub-phases are interviews/surveys, competitive analysis, and features listing.

The artifact for this phase documents these high-level requirements. The Software Requirements Definition is comprised of interview transcripts, survey summaries, competitive analysis reviews, and a features listing which mirror the activities of this phase exactly.

These high-level requirements usually provide enough information as to whether it will be advantageous for both the developer and client to proceed with developing the system. Based on the Software Requirements Definition, a go/no go decision must be made.

Go/No Go Decision

Several points should be addressed when deciding whether development of the system should proceed. Risks need to be examined carefully and completely. This is the point of committal for both client and developer. At first, this may seem like a cut and dry decision, but many times it is not. This decision should not be made hastily; it should rely upon the findings of the Software Requirements Definition and the capabilities of the project team. Input is highly recommended from those on the project team who will eventually implement the solution.

The artifact for this phase, should the decision be made to pursue the solution, is a contract between the developer and client. It should reflect the features list from the Requirements Definition as a realization for the client as to what will be delivered as the solution.

After a committal has been obtained from both developer and client, development of the system can proceed in a more specific manner. However, it is not yet time to start coding the solution. The reason is because of the condition of the requirements: they are still in very general terms, at least as far as the developers are concerned. The next phase aims to specify the requirements in a more concrete manner.

Requirements Specification

Here, we are still concerned with identification of the problem and not the solution. We are still trying to define, albeit more concretely, the capabilities or services which the system must provide and the constraints under which the system must operate. It is important that requirements gathered in this phase, and documented in the Software Requirements Specification, be as precise as possible and that the client signs them off. Even then, problems may develop if there is a significant delay between signing off the Specification and the final delivery of the solution.

One could logically argue this phase actually marks the beginning of development of the solution. Although we are not concerned with the how just yet, the how will stem directly from the what specified from this phase. Errors at this stage are the most expensive. The client sees requirements errors as problems requiring repair or modification. A typical response to an error made at this stage for the client would be, "It doesn’t work the way we expected." Developers may view errors made at this stage as incorrectly stated requirements accepted by the client. A typical response from a developer to an error made at this stage might be, "It does what the requirements specification says." Although it may seem difficult, it is crucial (because of the cost involved) to document requirements in a concrete and precise manner.

Needless to say, the artifact of this phase must be a very precise document. The Software Requirements Specification must be an unambiguous document and one that describes the requirements in a manner that is clear to the client and developer and precise enough for the developer to use as a jumping point for developing a solution. It would serve both developer and client well to have as much input as possible on critiquing this document, especially inclusive of business roles, technical roles, and engineering roles.

The Software Requirements Specification should now fulfill needs for requirements. At first thought, one may think that now that the what is nailed down, we should now turn to examining the how. That would seem to be the natural progression; however, the next phase takes a step sideways to prepare for a future phase.

System Test Planning

Now that the what has been clearly defined, both the client and developer can determine from the Requirements Specification exactly what the system should be capable of doing. Therefore, even at this early stage, plans can be made as to how the system will be tested.

In this model, user requirements are gathered through use cases. A use case is simply a capturing of one way a user of the system may interact with the system. A use case is comprised of a main success scenario, which is the ideal way the user interacts with the system to perform the task. There are also extension scenarios which describe alternate routes that may be taken (for example, if an error occurs).

Each scenario, both main and extensions yield one system test case. Not only must the system be tested for the ideal route, but it also must be tested for proper handling of extension scenarios. Therefore, there is a direct mapping between a use case scenario and a system test case.

The artifact for this phase is the System Test Design. It is mostly comprised of a simple enumeration of the test cases. When it comes time to test the system, this test design will be used as the basis for testing the system. Each scenario captured in the requirements will be verified against each of the test cases. While the system test design does not account for complete testing of the system, it does provide the foundation for a great majority of the testing phase.

After the System Test Design is completed, it is time to start thinking about how the system is to be built. The next phase in the Process Model is the design phase.

Design Specification

Before actual coding commences, it is important to plan how the system is going to be built. The analogy quickly comes to mind of building a house. One wants to make sure all measurements are made ahead of time before driving the first nail. In the same sense, the activities of this phase consist of describing how the system will be implemented.

Software design is describing the software architecture, showing what has to be built. Such a description entails such things as an outline of the modules required and data structures that will be used.

Many techniques have been suggested for doing software design: top-down design, bottom-up design, structured design, and object-oriented design. In each case, a design methodology provides the discipline for the design process. Often, the design methodology also provides a notation for writing some or all of the design. This notation may be textual, graphical, or a mixture of both.

This model's design phase uses an emphasis in the object-oriented design methodology. The Unified Modeling Language (UML) provides a convenient way of diagramming objects and their relationships. UML is used extensively in the object-oriented design methodology.

The "story line" of the design phase generally is as follows:

    1. Identify entities that play a role in the system.
    2. Identify attributes of these entities.
    3. Divide the system into subsystems.
    4. Denote actions in requirements use case scenarios as pseudo method calls.
    5. Map the entities from step (1) to the subsystems from step (3).
    6. Map the pseudo method calls from step (4) to the subsystems from step (3).
    7. Within each subsystem, map the pseudo method calls to the entities that call or categorize them.

This is a very general guideline for the design phase activities. Some steps may be added for complex systems while some may be omitted for relatively simple systems.

The artifact that documents the activities of this phase is the Software Design Specification. In general terms, this artifact is an adaptation of the Software Requirements Specification to tailor it more for the members of the development team which will actually implement the system. The client usually does not see this document; therefore, this document can be more technically oriented than the Requirements Specification. However, the Design Specification should translate directly from the Requirements Specification. Use case scenarios itemized in terms the client can understand are translated into pseudo method calls. The system is mostly described in terms of diagrams that allow for easily translation to program code.

After the system has been designed, the project team can commence building the system.

Implementation and Unit Testing

This phase involves translating each of the subsystems, entities, and method calls from the previous phase into appropriate programming language text. It is this phase that is that primary focus of most of an undergraduate computer science program. However, in actuality, it occupies relatively little attention in the grand scheme of things.

An important issue with respect to this phase is that implementation will be significantly easier if the programming language chosen to implement the system, or parts of the system, support the design methodology used to design the system or the part of the system. For example, the object-oriented emphasis in designing the business rules implies an object-oriented language be used to implement the business rules code. Most systems call for what is known as a distributed architecture. A distributed architecture allows not only for scalability, but also allows developers to split the system into tiers. Each tier can then be implemented in a different language, using the best language suited for each tier.

Another consideration in this phase is deciding on coding style guidelines. Things such as code indentation and commenting should be documented so that all developers may follow the guidelines. Following these guidelines can help immensely in code readability.

As the methods, entities, and subsystems are implemented, each unit should be tested. Several approaches can be taken here: manual code reviews, program proofs, execution testing, and structured basis testing.

The artifacts of this phase are a code base and the unit test cases. As the system is implemented, a code base is formed. This code base must be carefully edited as many developers may change parts of the code.

As parts of the system are implemented, unit test cases are designed, the code is tested according to these designs, and a report is made as to the result of the unit test case. Contrary to the design done for the system as a whole, the unit test case design is usually done after the code is actually in place. Unit test cases rely on what types of code structures are used. For example, if a "for" loop is used to iterate over a range of numbers, a unit test case would include a test for boundaries of this loop.

At this point, a code base has been formed consisting of implementations of the methods, entities, and subsystems described in the Design Specification. These units have been tested individually to make sure they function correctly as separate components. Next, it is time to validate the system as a whole to make sure it meets the functionality described in the Requirements Specification by validating the system against the test cases itemized in the System Test Design.

System Testing

In general, testing the products resulting from the implementation phase is part of a larger concern called quality assurance. A major goal of quality assurance is to verify that the implemented software system meets the Requirements Specification. Unit testing has been done to ensure the implemented code matches the design. System testing ensures the system does what the customer requires. As a consequence, the test cases that were itemized in the System Test Design phase are used as these test cases come directly from a customer-oriented requirements document (the Software Requirements Specification).

There are many techniques for system testing:

    • Functional tests
    • Performance tests
    • Acceptance tests
    • Installation test (this may overlap the next phase: delivery)
    • Phased tests
    • Regression tests

The artifact documenting the activities of this phase is a Quality Assurance Report. This report details the findings of each system test case itemized in the System Test Design. This report also details the findings of other system tests that are performed in the above categories (performance, acceptance, etc.).

As a part of testing (installation test), some type of setup routine is created to release the current iteration. That is the focus of the next phase.

Release

The purpose of this phase is to release the iteration of the system developed and tested thus far. This phase "releases" the current version. If this is one of the first iterations, there may be a number of caveats. These caveats are itemized along with the release to note problems with that release.

Not all releases are necessarily for the client. Many of the initial releases may only be intended for internal testing as system development progresses. All releases, either for internal or client purposes, should be archived along with caveats. The release along with the caveats comprises the artifact for this phase.

Going back to the introduction to the process model, the phases of Requirements Specification through Release are shared under a Development Cycle and a Maintenance Cycle. During the initial iteration, activities of the Requirements Specification phase through Release phase are done under the Development Cycle. Once the initial iteration release has been made, if the release is stable enough, the decision may be made to repeat the Development Cycle for the next iteration. This decision would be one of adding functionality. However, the iteration release may not be stable and may contain a number of bugs. If this is the case, the decision may be made to fix the current iteration and develop a point release. Development of this point release still proceeds through the phases of Requirements Specification through Release. However, these phases are repeated under the Maintenance Cycle (to maintain the current iteration release). In addition, there is a Maintenance Phase in between the Release Phase of the iteration being maintained and the Requirements Specification Phase of the upcoming Maintenance Cycle.

Maintenance

 

Maintenance as a Phase

When maintenance is considered as a phase, it is done so with the same perspective as other phases. That is to say, the Maintenance Phase is defined by its activities and is documented through an artifact.

The activities of the maintenance phase are characterized by completely identifying bugs that exist in the iteration being maintained. Identifying bugs completely involves first documenting who found and submitted the bug. This is done so that there can be a point person for whom to ask questions regarding how to recreate the bug and conditions in which the bug surfaced. This implies that the one who submits a bug be able to explain fully how to recreate the bug.

After fully realizing how to recreate a bug on demand, the next step is determine what module (GUI, business objects, database, etc.), or combination of modules, in which the offending code is located. Next, the bug is assigned to a development team member or combination of team members. The latter is more often the case because fixing a bug usually entails exercising activities of more than one phase (Requirements Specification through Release). One person is not usually responsible for all phases.

The artifact for this phase is a simple documentation of the finding of a bug and the intended plan for fixing it. While some of this documentation may overlap that done in Testing phase, it is repeated here for completeness. In this way, information on a particular bug is completely in one place and is not linked (i.e., "This is the plan for fixing bug #21 found in testing. Please see the Quality Assurance Report for more information.").

After the procedure for reproducing a bug has been itemized and resources have been assigned, maintenance continues in the Maintenance Cycle.

Maintenance as a Cycle

Entering the maintenance cycle has three prerequisites:

    1. Bugs have been found in an iteration release
    2. Project Management decides on a maintenance iteration to fix the bugs found
    3. Resources are specifically allocated for fixing the bug

The Maintenance Cycle consists of the same phases as the Development Cycle. However, activities in the various phases are exercised with the goal of modification instead of addition.

Remember that an error in one phase propagates as a defect in the following phases. However, identifying the phase where the error was made does not preclude previous phase activities from being exercised during the Maintenance Cycle. In short, all phases must be addressed when fixing bugs.

To take a very simple example, say that one function in a system is to loop over a collection of objects and set a property for each of them. During testing, it is found that all but the last object has the property set. During discovery of the cause of the bug, it is found that in looping over the collection, the code was hastily written and the last element was not addressed. This could be the result of writing a "for loop" definition as

for(int counter=0; counter<10; counter++)

where it should have been

for(int counter=0; counter<=10; counter++)

Thus, the error was made in the Implementation Phase. Presumably, unit testing would have found this boundary error, but it is used here anyway for illustration (this is a frequent problem often found in System Testing, so this goes to promote unit testing). Even though the error was made in the Implementation Phase, the activities of Requirements Specification through Design Specification are exercised in addition to Implementation through Release. The activities of the latter group may seem more apparent than the former.

When going through the phases in the Maintenance Cycle, it is important to update the artifacts of each phase. If the error was made in the phase, the artifact is modified to reflect the change. In addition and when the error was not made in the phase directly, an addendum is made to the artifact to document what was changed.

Therefore, in the example from before, the artifact in the Requirements Specification would not be modified. However, an addendum would be made to document the problem. Remember that during this phase, we are examining the what and not the how. Therefore, the addendum would consist of what the requirement prescribed, what was found to be the bug (only the last element was not touched), and what requirement should be reinforced (the last element should be touched). Following phases would be similar:

    • System Test Design: repeat test to make sure all elements are touched
    • Design: how the fix is to be implemented (for loop should include equality condition)
    • Implementation/Unit Test: the actual change in code as well as change documentation in the form of change comments (hopefully, the unit test will be more thorough this time)
    • System Test: ensure all elements are touched
    • Delivery: release point version with error fixed

Usually, more than one bug will be found in System Testing and these will be combined in one addendum to each artifact.



Last updated: 8/3/2000 20:00
Send comments to me here.
Copyright 2005 Jason Hyman
Version 2.0