Software Design Principles

CIS241

 

There are a number of software design principles that are crucial to the development of good, robust, high utility software systems.  Among them are:

 

Management of Complexity:

 

In The Mythical Man-Month, Phillip Brooks relates the story and the lessons that came from the design and implementation of one of the first truly large scale computer systems, the MVS operating system for the IBM 370 line of machines.  Although his primary focus was on the new set of problems attendant to the management of a team of software engineers, the underlying issue that was the source of myriad problems was complexity. 

 

No one had previously tried to build a system of such complexity.  The amount of coding involved was too great to be handled by one person, or even a small number of programmers.  A large team of programmers was required, which carried with it enormous problems of coordination.  Clearly, the difficulty of coordination was not due solely to the number of persons involved.  After all, armies of hundreds of thousands of soldiers have carried out complex and coordinated operations.  The enormity of the problem was inherent in the task itself.  The innumerable pieces of the software system had to be coordinated in precise ways and operate correctly under an astronomical number of configurations.  The software design techniques of the day were insufficient and the project was plagued with cost overruns and missed schedules.  After the product was delivered it was beset with numerous bugs.

 

Over the years, as the science and the art of software design have advanced, recognition has grown that the management of complexity is one of the central underlying themes of computer science.  It is evident in many aspects of the discipline.  Earlier in the semester we saw how it has influenced programming language design, how the necessity for the tight management of data flow and execution flow have given rise to data fences, data gateways, units of execution and execution flow constructs.  Thus, the need for the management of complexity has shaped the tools of the trade for the software engineer, the tools used in the coding phase of the software development cycle.  The time has come to develop tools to use in the design and analysis phases of that cycle.

 


State-Action Analysis:

Often, when we undertake the development of a software system, we are faced with a particular problem and our focus is mainly on how to devise a solution.  Often we do not realize that most of these problems have many solutions and, moreover, that a large number of those solutions carry with them unexpected side effects.  This state of affairs is exacerbated by the fact that, inevitably, we are faced with deadlines.  So, in most cases, we are just happy to find a solution, any solution, within the prescribed time period.  As a result, we will often find that the software we use has two very undesirable features:

      1. The user is “trapped” in an undesirable state

      2. In certain states, undesirable actions are enabled.

 

Here are examples of each.

 

User Entrapment:

You begin to download a file from Internet.  After about 30 minutes, it becomes clear to you that it will take at least 3 more hours.  It is 11:30 pm.

 

Undesirable Enablement:

You design a Keypress event to operate in conjunction with a Click event.  But, it turns out that by the nature of the IDE you are using the Keypress event does not require the Click event for enablement.  Therefore, the user can invoke procedures which make no sense in certain contexts.

 

State-action analysis can help to prevent both of these types of occurrences.  The process is simple in principle, but can be very complicated in practice.  Build a state-action diagram of all possible program states and all possible user actions.  Then analyze the resulting diagram, with these two principles in mind.

      1. For each state, be sure the set of enabled user actions is

         complete.  In particular, make sure a bailout action is provided,

         if one may be desirable.

      2. For each state, make sure the list of enabled actions is

          complete.  Examine each enabled action and determine that

          it makes sense in that particular context.

 

Exercises:

1. Analyze the examples provided of simple finite state machines (FSMs).

2. Draw a state-action diagram of the CheckSheet program.  Examine it with respect to the above two principles.