Software Engineering
Home Planning Requirements Writing Hazard Analysis Requirement Analysis Config Control Software Design Software Testing Software Standards Basic Logic

Software Design - Objectives

This is intended to be a short reference of basic software design concepts. The objectives are to:

  • Identify different types of software, based on the usage.
  • Show differences between design and coding.
  • Define concepts of structured programming.
  • Illustrate some basic design concepts.
  • See how to design for testability and maintainability.
  • Introduce some formal design notations.

This section is NOT:

  • About a specific programming language.
  • Advanced tips & tricks for coding (though I may add those later).
  • Detailed course on formal notations, such as UML.

Major Categories of Software

(Jones, Capers. Applied Software Measurement, and
Gamma et. al. Design Patterns, Elements of Reusable Object Oriented Software. )

End User

  • Written by the primary user(s). e.g:
    • Spreadsheet.
    • Basic program to analyze data.
  • Relatively small in size.
  • Small number of local users.
  • Least documented.
  • Highest defect rates.
  • Lowest test effectiveness
    (about 50% - 55%)

Application Software

  • Applications for general distribution. e.g.
    • Word Processor.
    • Graphics Editor.
    • Web Application.
  • Small to large in size.
  • Large number of users in remote locations.
  • Design documentation and user manuals.
  • Moderate to low defect rates.
  • Good test effectiveness
    (about 85% to 99%)
Toolsets
  • Libraries of functions for use by applications. e.g.
    • Third party ActiveX component.
    • Math library.
  • Small in size.
  • Incorporated into many application programs.
  • Detailed interface documentation.
  • Very low defect rates.
  • Very good test effectiveness
    (about 95% to 99%)

Frameworks

  • Reusable design for software applications. e.g.
    • C/C++ Complier.
    • Relational Database System.
    • Operating System.
  • Very large in size.
  • Used to create application software.
  • Well documented interface.
  • Extremely low defect rates.
  • Very good test effectiveness
    (about 95% to 99%)

Since Toolsets may be used in hundreds of applications, and Frameworks are very large in size, those two categories are the most intolerant of defects, hence must have the lowest defect rates. Applications and Frameworks also tend to be very large in size, necessitating even lower defect rates. Defect prevention quickly becomes more critical than defect detection.

Coding in the Big City

  • On a country road, I can probably get away without looking before I cross the road (my brother always got away with it, though we sometimes heard the squeal of brakes on the road).

  • However, in the Big City I’ll likely get flattened!

  • In the big city, requirements change, customers find bugs, schedules get shifted, team members have different interpretations of the requirements, and new requirements are added long after software deployment.

  • Moral: design and coding practices that may be adequate for end-user software can get you flattened when writing applications, toolkits, or frameworks!

True Horror Story

It is common for C programmers to use bit flags for error bits. A single unsigned integer gives 32 possible error bits. In a safety critical application, the senior developers had used a 32-bit unsigned integer in just this fashion. However, a few months into the project they reached the 33rd critical error that had to be tracked. Their solution: was to add a second error variable.

They had to add the second error variable in *every* location where they checked for errors. There were over 50 such locations. They forgot two. The result was a safety related defect that resulted in the recall of medical device software.

Had they instead used an error object, they could have changed the internal implementation to accommodate additional error flags without impacting the rest of the code.

Major Categories of Programming Languages

Programming languages fall into two major categories:

  1. Procedural. Lines of code are executed in a defined sequence, one after another. Branch instructions change the flow of control. Some example languages are: machine langauge, assembly, C/C++, Basic, Visual Basic, Pascal, SmallTalk, and Fortran, Java, JavaScript.
  2. Declarative. Lines of code constitute rules that are interpreted by an engine. Program flow is determined by the engine. Some example languages are: Prolog, LISP, PALASM, VHDL, SQL.

Another way of categorizing langauges is by the distance from the hardware:

  1. First Generation - uses the native machine code of the processor. Programmed in raw 1's and 0's. Code only runs on that processor.
  2. Second Generation - uses mnemonic codes to represent the native machine code. For example, instead of writing a line of code that looks like 1101111000010110, you would write a line like:
    move a, c.
    In a second generation langauge, one line of code generates one line of machine code. Code only runs on that processor. Some example langauges are Assembly, PL/M, and PALASM.
  3. Third Generation - uses more abstract concepts, like A = B + C. Each line of code generates several lines of machine code. In some cases, the code only runs on that processor; however, languages like Java and JavaScript can run on different types of processors. Some example languages are: C/C++, Basic, Visual Basic, Pascal, SmallTalk, Java, and Fortran.
  4. Fourth Generation - abstracts the programmer from the procedural nature of the code and focuses on the business rules. Languages tend to become more declarative. Program can run on any machine that has an engine for the language. Some example langauges are: SQL, LISP, Prolog, VHDL.