Incorporate my: Introduction to OOSD, especially Modularization: O vs SP, and (perhaps)  Algorithmic Pb. Solving.
Add questions, from this LM, to the FPE?

alert_red.gifupdated.gifLAST UPDATE: 12/5/06alert_red.gif
Currently under REconstruction
This is the most current version of Learning Module IX; however, the FIB/SAQ/TPQ tools have yet to be included.
Also the study guide needs to be written (for the independent learner) and
some of the content sections, links, and assessment tools need to be fine-tuned.  (Nothing is wrong, just imperfect!)
Note that the blinking text designates things that I need to work on; the material is not wrong, but can be improved.
(Don't worry, I don't like blinking text, either, so there will not be any in the finished product!)

LEARNING MODULE IX:
SOFTWARE DEVELOPMENT

        In its most fundamental form software development is the programming of a computer. Nicholas Werth, the designer of the Pascal programming language, said that a program consisted of its algorithm (the detailed method of solution) and its data structures (the way data is organized). This basic view was the foundation of "structured programming", a strategy for efficiently developing software in the 70's and 80's. In the 90's the methods of structured programming have been generalized into a higher level strategy called object-oriented programming (OOP) or object technology (OT), which has yet to mature, but is definitely the "wave of the future". Regardless of the strategy, the efficient development of quality software has been the first skill that must be mastered by computer professionals. In the early days of computing (as well as in current university computer science curricula), programming was essentially an individual undertaking. However, as software became more sophisticated, software development evolved into a group enterprise. Now "computer programming" has given way to "Software Engineering" which incorporates the design, production, and maintenance of software as if it were an engineering project involving a team.  Independent learners should read the objectives and sequence of presentations, summary, then the Study Guide for this learning module {NOT WRITTEN YET}.

The Objectives of this learning module are:

  1. to illustrate how the software development cycle fits within the system development life cycle,
  2. to describe the stages of the software development cycle,
  3. to present the basic principles of structure programming as a subset of object oriented programming,
  4. to survey the basic principles of object oriented programming and component development, and
  5. to describe some of the design tools currently used in software development.
TPQ 1: Rewrite the preceding objectives in terms of personal accomplishments to be attained after finishing the study of this learning module.

The sequence of presentations in this learning module is as follows.  You can click on any link to jump directly to that section.


1. SOFTWARE DEVELOPMENT IS PART OF THE SYS. DEV. LIFE CYCLE:

  1. When produced in-house, initial software development occurs in the Systems Development Phase of the system development life cycle.
  2. Software development, in practice, does not end with the completion of the Systems Development Phase but is an unending cycle occurring within the Systems Maintenance Phase; see section 2, below.
2. SOFTWARE DEVELOPMENT CYCLE:

        Regardless of whether software is developed commercially or as part of the systems development life cycle the programmer (software engineer) must do the following.  Note that modern strategies for software development are NOT linear, i.e. the following steps are not performed in a strict sequence.  Instead they are part of an iterative (nested looping) process conducted on each independent part of a software application.  However, the following activities are all essential to software development and are performed, at the

  1. Analyze the task or system you are modelling and Specify its Input/Output.
    1. Identify data to be used and the results to be output.
    2. Identify the operations that process the data.
    3. Specify the interface to the processing (the I/0 mechanism)
  2. Design a model that implement the specifications using a "divide and conquer" approach (analagous to starting a theme by developing an outline) .
    1. Define first level modules
    2. Refine, stepwise, the module details (often in terms of submodules).
    3. Deskcheck and Debug
  3. Code top-down in a computer language thus creating your prototype software.
    1. Code modules using "stubs" for untested components
    2. Test and debug with each newly coded module
  4. Test and debug your whole prototype software, using a computer, with a complete set of realistic test dat.
  5. Maintain by constantly checking for faults, incorporating improvements, updating with system changes, etc.  This final stage also includes a Document phase (that is often distinguished as a separate phase) where tutorial and help features are added so that your software is user-friendly and easily modified and extended for future updates.
As mentioned above, the linear sequence (called the "waterfall" approach) is an oversimplified strategy.  In practice, although the activities are the same, they are incorporated in an iterative strategy during which activities are repeated, e.g. mistakes may be detected in the test and debug phase which will necessitate going back to the Design phase.  The waterfall and iterative approaches are compared in the following illustration.


 

FIGURE SD-1: COMPARISON OF SOFTWARE DEVELOPMENT LIFECYCLES

From the pamphlet, "The Rational Approach"

These separate activities are discussed in more detail in the following sections, but first It is important to recognize  a fundamental change is occuring in computer science
The "object oriented" paradigm (way of doing things) has replaced the structured "programming" paradigm in modern software development.  The following table empahsizes the necessary shift in terminlogy required to upgrade from structured programming (SP) to object oriented software development (OOSD).

 
 
Paradigm
Abstract Foundation
Abstract Representation
Software Implementation
Programming
algorithms
flowchart; pseudocode
program
Object Oriented
1. object architecture models
2. operation algorithms
1. UML diagrams 
2. SAC for algorithms
O. O. S'ware Architecture
OO stands for "object oriented".
UML stands for the Unified Modeling Language, the standard Object Technology, explained below.
SAC stands for (Tony'snon-standard) Structured Algorithm Charts, a structured programming version of flowcharts






Unfortunately, as far as I have seen, the majority of texts and even some teachers have not made the upgrade to the UML.  This can be very misleading to novice software developers and results in a great deal of confusion and frustration in core software development courses (COSC 101,  COSC 240, COSC 241), common to all computer science major and minor programs.  I have tried to address this challenge in three online presentations introduced by my Concise Introduction to Software Development.  (Note that these are rather advanced subjects, but future computer science students shoul read them and come back to them while studying COSC 101, COSC240, and COSC241.)  I believe that, if I can adequately present this (NOT an easy job!), I can help Comp. Sci. students to understand "what they are doing" when they write "programs".  (I don't even use the old fashioned word "program" because it, itself, is part of the confusion; however, most of the rest of the computer science community does use "program" all over the place, so all I can do is warn you and play the "devel's advocate".) If you do take COSC 240, let me know if this helps (or, if it is improved, it could help).  If you are interested in learning JavaScript, the language I recommend for novice software developers for 13 reasons, then you might try to work through the JavaScript Thread that is part of my course COSC 330.

2.1 The Analysis/Specification Phase:

  1. Identify the Task and decide whether or not a computer approach is required.
    1. If a task is to be carried out only a few times the time and effort of developing a program probably is not warranted.
    2. Tasks that are to be repeated many times with different data or conditions are ideal candidates for computerization.
  2. If a computer approach is to be chosen, software specifications must be made, i.e.
    1. output: specify the content, format, timing, and flexibility of what is required.
    2. input: specify the needs, availability, methods of gathering, and methods of entry.
    3. processing: specify the tasks and constraints (user sophistication, hardware capabilities, interfaces to other software, etc.) In the older structured programming approach algorithms are specified for each task; in OOP, one defines objects (data and behaviors) and relationships between the objects.
2.2 The Design Phase: Defining the details of the Software Model:
  1. Before writing a program one must develop the step by step logical process that will accomplish the specified tasks.
    1. A common mistake of novice programmers is beginning to code (write the program instructions in a programming language) before they completely understand the task and the method of accomplishing it.
    2. The design should NOT be done using the programming language. In fact, unless one is using computerized software design tools, one should design the software architecture away from the computer in order to resist the temptation to code parts of a program before the design is complete and debugged.
  2. Modern programmers used structured techniques (See section 3, below.) and object oriented programming (OOP) techniques (See the Learning Module, Programming Languages.) to construct modular software components by using only:
    1. structured logic constructs of sequence, selection, and repetition and
    2. modular constructs: In structured programming, procedures (in which data is passed to the main program via "parameters") and functions (in which data is returned via the function name) are used to modularize the program design. In the more modern OT, classes (in which data and operations are "encapsulated" together) are designed; these become "templates" for the actual objects used in a program.
  3. Program design tools are usually utilized to help the designer to think through the algorithm. The following are presented in more detail in following sections.
    1. Structured programming tools include structure charts, flowcharts, and pseudocode.
    2. OOP tools are still evolving; one such tools is the Unified Modeling Language or UML.  (See section 5.D, below.)
  4. Rather than developing applications "from the ground up" using the basic constructs of traditional programming languages, many standard applications can be created quickly using special purpose facilities such as VHLL, CASE, application generators, etc. When planning to use one of these facilities, one can assume a wider range of more sophisticated constructs from which to create an application thus avoiding many logic details.
  5. Deskcheck  and debug means to check your design (UML diagrams, flowcharts, etc. - NOT code) with a simple, but complete, set of test data to see if you get anticipated results.
    1. Deskchecking (also called tracing or structured walkthroughs) is the process of manually performing all operations, using pencil and paper, with simplest, complete test data.  The test data should be as simple as possible (so that math, for example can be done in the head) but it must be complete (tests all possible variations of input/output), i.e. the input does not have to be realistic, just complete.  (For example, checking for a paycheck algorithm one would use a salary of $10/hour rather than $7.53 even if the latter is more realistic.)  Ideally deskchecking would involve working through all the "paths" of the logic, but, of course, this would be impractical for anything other than the simplest algorithms.  
    2. Debugging  (to get rid of the "bugs", i.e. the faults, in your design) means correcting each design fault that is discovered during deskchecking. It is a common failing of novice programmers to rush to the coding phase before thoroughly checking the correctness and completeness of their design.
2.3 The Coding Phase:
  1. Coding is the actual writing the instructions of the algorithm in a programming language using a development tools, associated with the language. The choice of language in which to code an application is very important because different languages have different capabilities; one should try to choose a language which will make implementation as efficient as possible while satisfying other constraints such as availability, your programmer's familiarity with it, etc.
  2. Coding should be done top-down (i.e. main program first, followed sequentially by each module, in order of priority) using "stubs" for each untested module. Testing/debugging should be done at each stage.
    1. "Stubs" are trivial components that consist only of the procedure, function, class, or method name with simple output statements indicating (1) that the component has been called and (2) when it is completed. It is usually helpful to output the values of the important variables and parameters with each output statement, so that logic errors can be pinpointed when the program is executed.
    2. It is critical that the whole program should be tested and debugged when each component is implemented, i.e. when each stub is converted into a fully operational procedure or function. Because this is being done on the computer, more sophisticated test data can be used than during the tracing/debugging of the deskchecking (tracing) phase of the Design phase.
  3. The following conventions are used to standardize many of the features of a program:
    1. structured constructs in the logic of a program (universally required),
    2. naming conventions,
    3. documentation (comment) standards, etc.
  4. As mentioned above, the following application generators automate many of the tedious tasks of coding and thus greatly increase programmer productivity in applications that have standardized characteristics.
    1. a. VHLL (Very High Level languages), including 4GLS (Fourth Generation Languages), are special purpose programming languages that facilitate efficient implementation in a particular (limited) domain of applications (e.g. 4GLs are very efficient to implementing database applications but would be cumbersome, if not incapable, in writing graphics applications, for example).
    2. CASE (Computer Assisted Software Engineering) which generate program code directly from specifications thus allowing the developer to avoid worrying about the details of the program logic.
  5. Other facilities that increase the efficiency of application development include:
    1. Reusable code: Very often a procedure or function can be used in more than one program. In such cases they are placed in code libraries from which they can be "cut and pasted" into various applications. Many standard libraries are supplied with programming languages and public domain libraries can be freely copied. In OOP code reuse is greatly facilitated with "inheritance" by which classes can share the data and operations defined in "parent classes".  (See section 4.1, below.)
    2. Data dictionaries (particularly associated with DBMS): These carry a complete specification of the data processed by a program; this can be accessed by programmers to help them in application development. Active (on-line) data dictionaries will give error messages if data is improperly used in a program.
  6. Quality assurance is maintained by structured walkthroughs, i.e. a detailed peer critique of program. This team approach encourages egoless programming.
2.4 The Testing and Debugging Phase:
  1. Debugging should actually take place continuously during the development cycle. In particular it should be done in both the:
    1. design phase: This involves detecting and removing logical errors. It is accomplished by "tracing" the algorithm (penciling through each step); this is also called performing a "walkthrough"
    2. Coding phase: This involves removing syntax errors which are mistakes in the spelling and grammar of the particular programming language.
  2. After coding, testing and debugging is needed to catch faults that might have slipped through.
    1. Testing involves using simple but complete test data specifically chosen to expose possible errors ("bugs");
    2. Debugging is the process of removing these errors.
2.5 The Documentation Phase:
  1. Program documentation are explanations that will help a user, operator, or programmer to understand the program or that will help someone to later .
    1. User documentation consists of general manuals on how to use the application.
    2. Operator documentation consists of technical manuals to help operators to modify or customize the application.
    3. It often becomes necessary to modify or update the program itself. Programmer documentation facilitates such "program maintenance". This includes design specifications, logic description (flowcharts, pseudocode, etc.; See below.), the program listing, and I/O specifications.
  2. Types of Documentation:
    1. External documentation describe overall purpose and design of the program and its components.
    2. Internal documentation are comments, inserted directly into the code, that explain the specific parts (components) of the program as well as obscure sections of the code.
2.6 The Maintenance Phase:
  1. Programs should grow with the user's needs. If an application is designed so that it can be updated to accommodate changes, then it is "maintainable".
  2. Most companies have "maintenance programmers" whose primary job is to keep the company's applications up to date.
3. STRUCTURED PROGRAMMING (METHOD DEVELOPMENT IN OOP):

        Structured programming, a disciplined strategy for developing and maintaining efficient programs, was developed in response to a growing crisis in the programming community in the 1960's, runaway software costs. This crisis had its roots in inefficiencies that were inherent in early programming languages:


During the 80's structured programming was emphasized as the key to quality software development, but this has been superseded by Object Oriented Software Development, more popularly known as Object Oriented Programming.  (See Section 4.)  This does not mean that structured programming is no longer worth learning; on the contrary, virtually all the principles of structured programming are within OOP, i.e. structured programming techniques are needed to write the "methods" of OO software.  Structured programming is based on two fundamental principles (which are also essential in OOP), structured control constructs (See section 3.1.) and modularization constructs (See section 3.2.).

3.1 Three Fundamental Structured Control Constructs:

        In modern structured and OO programming, human-oriented logical operations (control structures) are used. In fact, any programmable problem can be coded using only three different control structures:

  1. Sequence: the default order of program execution, one instruction after another.
  2. Selection: this control structure allows the program to choose one of two or more alternative sets of instructions (subtasks). It involves evaluating a "selector", and, depending on its value, deciding which (if any) set of instructions to execute before passing control to the instruction following the selection.
    1. The most fundamental form is the If-then-else construct which facilitates selection on one of two, mutually exclusive sets of instructions. It is the "selection" constructor from which all others can be created, e.g.
if Grade >= 60 then
     print "Pass"

else
   
print "Fail"
endif
    1. The case statement provides for more than two selection categories.
  1. Repetition: the repetition of a block of instructions may be accomplished two ways.
    1. Iteration (or looping), the most common form of repetition in data processing languages, is the cycling through a block of instruction over and over until a condition arises that halts the looping. There are two fundamentally distinct types of loops:
      1. definite loops have a predefined number of repetitions e.g. for Index := 0 to 9 print (Index); (* A Pascal "for loop" *) repeat 4 [forward 50 right 90] ; A Logo "repeat loop"
      2. indefinite loops repeat themselves while a looping condition is true or until an "exit condition" occurs within the loop body, e.g.
        1.  
          repeat (* A Pascal loop printing out all the grades of a file *)
            read (Grade);
            print (Grade);
          until EOF (* EOF is an "End of File" marker *)

    2. Recursion, the preferred method of repetition in artificial intelligence languages like PROLOG, LISP or Logo, involves a subprogram "calling" itself (i.e. doing its instructions) over and over until a condition arises that halts the repetition.  For example,
3.2 Modularization, in Structured Programming, involves breaking a task/program into "subprograms"(procedure or functions):
  1. Modular programs consist of semi-independent subprograms (the "components") that perform well-defined, distinct tasks within the program; each component is identified and accessed by a unique name. These subprograms can be developed, debugged, or modified without effecting each other or the main program.
  2. Structured programs are a hierarchical collection of modules where modules may be nested within other modules. Each module has only one entry point and one exit point. OO programs consist of module templates called classes from which objects are created.
  3. When written in terms of these subprograms, the main program (or top level) looks like an outline of the program or an architectural composite of classes and their relationships; the details of each subprogram are hidden elsewhere in the code. By carefully choosing the names of subprograms the main program will read like summary of the program.
  4. Subprograms can be incorporated into subprogram libraries where they act as permanent extensions to the programming language itself.
  5. Modularization in programming is discussed in more detail and compared to modularization in OOP in my Modularization: O vs SP.
4. OBJECT ORIENTED PROGRAMMING:

        Object oriented programming, a superset of structured programming,  means that, software developers think in terms of "objects" which have a "state" (definded by its "attributes") and "behavior"( defined by its "methods").  For example, consider a window on a computer screen; its attributes would include its location, its size, whether or not it scrolls, etc and its methods would programs that define its ability to be opened or closed, moved, resized, etc.  In other words object-oriented programing (OOP) is a human-oriented view of programming rather than a computer-oriented view. In fact "programming" is an old-fashioned term that is being abandoned in favor of "software development".  One now hears the term "Object Technology" (OT) when referring to the OO field as a whole and "object oriented software development" (00SD) when referring to the writing of object oriented applications.  OOP benefits include simplifying the ways both users and programmers utilize computers to making code more reusable and modular. Perhaps the most visible impact of OOP has been the event driven graphical user interface(GUIs).

4.1  Characteristic of OOP include:

  1. Similar objects can take advantage of being part of the same "class" of objects.  A class is an abstract "template" for creating objects, but an object is an "instance" of a class.  For example the idea of a computer window would be a class, but the actual window which contains the text you are reading is an "instance" of the class window.  Each instance of the class window would have different values of class attributes (location, size, etc.) but all would share the same methods (movable, resizeable, etc.)
  2. Perhaps the greatest asset of OOP is its built-in facilities for reusing code, making software development more efficient.  This can be accomplished three basic ways:
    1. Classes can inherit the code (attributes and/or methods) from a parent class (or superclass).  Inheritance is used to "derive a subclass from a superclass", i.e. the subclass inherits the attributes and methods of the superclass and new attributes and methods can be added thus distinguishing the subclass.  Thus the subclass is a special case of the superclass and one can describe inheritance as an "is-a" relationship between classes, e.g. a the Car class would be a subclass of a Vehicle class or a "car is-a vehicle".
    2. Classes can contain other classes, i.e. incorporate code already written for other classes.  Containership (the proper word is "aggregation") is called a "has-a" relationship between the classes, the Car class would be defined with an engine as an attribute, but if Engine were a class itself, one would say that the Car class has-a Engine class, i.e. the Engine class is contained within the Car class.
    3. Methods within a class can make use of other classes as well.  This dependency of one class on another is called the "uses-a" relationship between classes.  For example a method called drive of the Car class might be written using the class SteeringWheel (must be one word), in which case one would say the Car class uses-a SteeringWheel class.
  3. Objects are thought of as "nouns" that a user might relate to rather than the traditional procedural "verbs."
4.2  The Object Oriented Approach to Software Development.:
  1. The evolution of programming procedures has, for a long time, be approaching an engineering viewpoint where "software engineers" construct "software architectures" from "software components".
    1. The software components are the classes so a software architecture (program) is a collection of related classes.
    2. A architecture is created as a software model of the real world concept such as a word processor, computer game, Internet browser, etc.
  2. Modularization in OOSD, involves in dividing you model into classes, one for each abstract object of your model.
    1. ....
    2. Modularization in OOSD is discussed in more detail and compared to modularization in OOP in my Modularization: O vs SP.
  3. OOSD, from an oversimplified viewpoint, simply consists of:
    1. Identifying the classes, their properties, and the relationships between them that correctly model the application being created.
    2. Defining the classes which involves
      1. defining all the essential attributes
      2. writing the code for all the methods that are needed to model the object's behavior.  All the tenants of structured programming are applicable to method development in OOSD; this is the reason one can say OOSD is a superset of structure programming.
      3. Specifying access controls that govern how much access the user has to particular class.
    3. Defining the relationships (inheritance, aggregation and dependencies) between between the classes of a software architecture.


5.  SELECTED PROGRAM DESIGN TOOLS (NOT COMPREHENSIVE) :

  1. Structure Charts illustrate the hierarchical format of an algorithm, but, unlike flowcharts and pseudocode, they do not specify the logic.
    1. Structure charts look like a "tree of subprogram modules".
    2. Structure charts are often used at the very beginning of algorithm development to break the overall problem down into manageable little problems (the "divide and conquer approach"); at this stage it helps to avoid worrying about the details of the actual logic of the algorithm.
  2.  Flowcharts diagrammatically illustrate the logical flow of an algorithm. Flowcharts fell from popularity with the advent of structured programming, but structure program flowchart or structured algorithm charts incorporate the ideas of Section 2 into the flowchart mechanism.
    1. Advantages: Flowcharts are language independent and thus emphasize the algorithm, not its implementation. "A picture is worth a thousand words!"
    2. Disadvantage: Traditional flowcharting is "old fashioned" and is machine oriented, i.e. it is oriented towards how the computer executes instructions rather than how the human organizes an algorithm. For example, the single decision construct is used to represent both selection and repetition in flowcharting; making a decision is what the machine does, but, from a human viewpoint, there is a fundamental distinction between selection and repetition.  (Structure flowcharts or structured algorithm charts do not have these drawbacks because they have separate symbols for each control structure and eliminate the arrows of flowcharts, because those arrows represent the notorious "gotos" that are not used in structured programming.)
  3. Pseudocode is the representation of an algorithm in concise English-like phrases governed by an indentation scheme that illustrates the logical flow of the algorithm.
    1. Advantage: Since no symbols are used, algorithms can be done by a word processor and communicated easily over networks and telecommunications.
    2. Disadvantages: It is not symbolic and therefore does not emphasize the language-independent "idea" of an algorithm; it is tied to the English language. It is wordy and thus does not make the logical flow of an algorithm as apparent as a diagram does. It does not differ significantly from programming languages themselves.
  4. The OOP analysis and design tools are beyond the scope of this course because they are complex, new, and require an understanding of OOP . There is a new standard for notation Unified Modeling Language (UML), designed by Booch, Jacobson, and Rumbaugh, three of the preeminent innovators in OO analysis and design. This new standard has finally introduced consistency into the terminology of OT and the graphical representation of the design of OOP.   However, there is currently no standard "process" of how to use UML to create software architectures (an engineering term that is superseding the word "program').
6.  SUMMARY {WRITE THIS!}