SOFTWARE ENGINEERING

Life Cycle of a program is the many phases the program undergoes from the initial conception to its ultimate demise.  The three fundamental stages are:
1.    Development where the new program is created, and when is is complete without any errors, it is released to the users.
2.    Use where the users use the programs.  If the users discover any errors not caught in the development stage, the errors are corrected by the development team.
3.    Maintenance where the programs are modified, enhanced, and deficiencies eliminated.  Software does not degrade, so the goal of maintenance is to improve the program.  If the changes are serious or numerous, new corrected versions of the program are released, or if the effort is too time consuming and not worthwhile, it is abandoned.
In most instances, development use and maintenance occupies much larger effort and is often more difficult than development (See figure 10.2 on page 571).

The four phases that characterize software development are:
1.    Requirements:    Specify what the program must accomplish, indicating the tasks that the program must perform rather than how to perform them.
2.    Design:        Indicates how a program will accomplish its requirements. Specify the interaction between classes and objects.
3.    Implementation:    Write the source code that will solve the problem.
4.    Testing:    Find and fix errors and improve the quality of the program.

Software Development Model is an organized strategy for executing the steps necessary to create high-quality software.
1.    In a Build-and-fix approach, the programmer creates an initial version of a program, and then continually modifies it until it reaches some level of acceptance.  Since testing is not systematic or properly planned, problems are undiscovered.  This is a reactive rather than a proactive approach and should be avoided.
2.    The waterfall method (so called as one process flows down into the next) is linear and was introduced in the 1970's.  This process has no provisions for feedback and revisions.  The stages flow forward.  They are: (See Figure 10.5 page 574)
        a.    Establish requirements
        b.    Create design
        c.    Implement code
        d.    Test system
Notice that these are the same four phases introduced earlier.
3.    Iterative development has the same stages but allows for feedback and to revisit earlier stages for revisions. (See Figure 10.6 page 575).  One danger in this approach is the possibility that not enough effort is provided in the initial development.

Testing is an important phase.  Walkthrough is a common technique wherein several people carefully review and evaluate design documents and/or code.  A design walkthrough determines whether the requirements are addressed and assesses the manner the system is decomposed into classes and objects.  A code walkthrough how faithfully the design satisfies the requirements and implementation represents the design.  It should identify any potential problems leading to failure of the design or the implementation.

In Black-box testing, test cases are developed without regard to the internal workings, and are based on inputs and outputs.  It is successful when the user provided inputs produces the expected output.  They are derived from the requirements of the system or from the stated purpose of the method.  The input data is often an equivalence category, which is a collection of inputs that produce similar outputs.  If it works for one value, it will work for all values.  So only one value is checked.
White-box (also called Glass-box) testing (also called statement coverage) exercises the internal structure and implementation of a method.  The goal is to ensure that every path through a program is based on the logic of the code.  It tests the possible paths and ensures that the test case causes every path to be executed.  In an IF..THEN..ELSE, make sure that input values proceed through every possibility.

A prototype is a program or representation of a program that is created to explore particular characteristics of the proposed or evolving system.  Prototypes explore all issues so that the final product is acceptable to the client.  It may be a simplified version o a small program that tests the classes.  They test the feasibility of specific requirements.  It calls attention to problems that a list of requirements might obscure or miss.  It can be used to reject certain design or implementation decisions before they become a problem.    It is a "quick-and-dirty" test of an idea or a concept.  It should not take much effort to develop.

Evolutionary prototype (or development) is carefully designed, and takes longer to develop than a throw-away version.  Its purposes are to allow specific aspects of a program to explored and to make it a part of an evolving software system when exploration is successful.  A major aspect of this model is the refinement cycle.  A refinement focuses on a single aspect of a program, such as the user interface or a particular algorithm.  Each refinement focuses on fleshing out one aspect of the overall system.  Part of refinement can be devoted to addressing problems that were established during the testing of a previous refinement, making the process iterative as well as evolutionary.

The refinement cycle is performed many times until all parts of a program are completed, tested, integrated, and released to the user.  The steps in this process are:
1.    Establish requirements
2.    Architectural (also called high-level) design establishes general structure and responsibilities of system elements.
3.    Establish refinement scope
        a.    Identify classes and objects
        b.    Identify relationships
        c.    Detailed design
        d.    Implementation
        e.    Unit and integration test
3.    Establish refinement scope
4.    System test
5.    Release.

Notice that Establish refinement scope comes twice and a through e (detailed design stage) are in a loop.  These are specific methods and algorithms.  This is the refinement cycle and repeated if necessary.  See Figure 10.7 page 581

The refinement scope (which may be broad - addressing a large portion, or narrow - focussing on a particular detail) is a set of objectives to be addressed in a particular refinement, which include:

The goals of the refinement cycle must be well defined and achieved.  Refinements allow a programmer to focus on specific issues without having to embrace the complexities of the entire system at once.  The steps of the refinement cycle are:

1.    Identifying classes and objects to determine which requirements relate to the current refinement, and to associate them with the part of the software that will fulfill that requirement.  Types of objects are:

Another technique for identifying objects is to review the requirement documents and highlight the noun phrases, which indicate a represented object or class.  After identifying the objects, identify the classes used to define them.

2.    Identifying relationships is the manner each class relates to the others.  The three primary relationships are:

3.    Detailed design.  Identify all the methods of a class, including those to satisfy the assumptions of any previous refinement phases.  Determine the data contained in each class and object and the manner in which it is modified..  Identify initial values and how they will be modified.  Document the algorithms (using pseudocode) to perform unusual or crucial tasks.

4.    Implementation.    Follow all coding guidelines and produce readable and clear source code.  Consider the impact of serious obstacles discovered during implementation.  A stub object or method can be used as a placeholder for future methods or objects.

5.    Unit and integration testing.  Focus on specific pieces and nuances involved in making the pieces interact.  Test the classes for a particular refinement, separately at first (a unit test targets one particular piece of a system such as a class or method) and then the classes are integrated with previous refinements.  Integrating one piece of code with another may uncover errors, even if the code worked separately.  Full system testing is the ultimate integration testing.