March 21 – Lecture Notes for Intro to Software Engineering


The midterm will cover reading material and lecture through “The Software Dock”, with the omission of project management material from Chapters 1-11 of Brooks The Mythical Man-Month.  The test will be made up of:

-          7 True/False (3 pts each)

-          6 Multiple choice (4 pts each)

-          4 Essays (10 pts each)

-          1 Essay (15 pts)



Continuing with Parnas, Designing SW for Ease of Extension and Contraction


Last week – Virtual Machines – extension of the idea of abstraction, providing a coherent set of instructions


4)       Hierarchy – define a “Uses” structure

  • Use relation – A uses B.  This means that:
    • A uses the interface of B
    • A uses the implementation of B (means we’ve exposed something within B)
  • Use != Invoke, though they often coincide, they are not necessarily the same thing
    • Especially related to data structures… you use data structures, you don’t invoke them
    • A is correct independent of B
    • A uses B, even though it never invokes it, requires the presence of a correct version (interrupts)
  • Elegant simplicity – pieces that can be independently built
    • Disadvantage of “usage” of components is that parts become highly interdependent
    • In practice, there is some duplication (sometimes it’s easier to write your own or manipulate, rather than go find a standard library)

*** reify – means to make concrete (like trucks), so what is the opposite of reify?  Abstract, destroy, obfuscate


  • User hierarchy
    • Restriction – no loops
    • Levels
    • Each level is testable, usable subset of system
    • Each level can be broken in to subsets
    • Major milestone (millstone around the neck)
  • Criteria for a Use relation – A “uses” B when all of the conditions hold:
    • A is simpler, because it “uses” B
    • B is not more complex, because it is not allowed to use A
    • Useful subset containing B and not A
    • There is no useful subset containing A but not A
  • Mutual dependency, programs can use each other (sandwiching)  B1 -> A -> B2

*** Parnas does not address the idea of co-routines, two routines that cooperate… A and B, executing concurrently, independently, or sequentially, or executing back and forth, or synchronizing…. Some things are naturally feasible that way… coding and design for example… coding usually begins before design is complete.  Parnas is valuable because he has been instrumental in institutionalizing a number of software engineering concepts (modularity, encapsulation, the localization of changes).  He takes parts of the problem space, and encapsulate that in the architecture and design.  He does not worry much about the shape of the solution being shaped like the problem (world versus machine, M. Jackson).  Many people neglect this motivation, and ironically, the solutions that are “elegant” often end up mirroring the problem.

  • Summary of this article
    • Requirements include subsets and extensions – subsets allow incremental development
    • Virtual Machine advantages (over conventional flowchart design) – provides an organizing principle for abstractions (conceptual integrity)
    • Difference between software generality and flexibility
      • General means it doesn’t have to change
      • Flexible means that it will need to change, and is easy to do
    • Distinction between modules, subprograms, levels
      • Modules – collections of small programs
    • Avoid duplication – difficult to make changes in multiple places
    • Designing for subsets and extensions can reduce the need for support software, because you can build bottoms-up
    • Extension at run-time versus extension during sysgen
    • Value of the model itself


*** Satsificing – coming up with a solution that is just enough to solve the problem (Herb Simon)


Example of an “abstract” interface:  a file – is an interface, to a character stream that is mapped to a disk, via inodes, etc.  The file and the standard file operations are an abstract interface that “hides” all of the issues of the hardware interaction, etc.  This comes up in Parnas papers, in the design papers, and in the next paper.


MIDTERM Info:  I will not ask about McDonald’s, or any details about any of the examples.  I am interested in your understanding of these basic principles, and WHY they are important.  I will ask no details about the programming calculus.  True/False and multiple choice are aimed at recognition, to trigger the easiest form of recall, learning.  Essay questions are trying to relate things that might not have been related in class, or for example, “what are the three most important aspects of… and why are they important?”





GENERAL SUMMARY – not in the readings

Three Primary tools

-          Modularity – breaking things into pieces

-          Encapsulation – localization, put related things together

-          Abstraction – different flavors: hiding information, (Lampson – “keeping secrets”), or generalizing or simplifying ( = information hiding)

o        abstract objects – abstract interface + object

o        abstract types – abstract interface + implementation… these can then be instantiated (objects can be declared, such as strings, lists, stacks, etc)

§         Data abstraction – values

§         Type abstraction – structure

§         Procedural abstraction – processes (of abstract procedures and functions)




Lampson, Hints for System Design

Hints collected, summarized:

  • Why do these things help make a Good System:
    • Function (does it work)
    • Speed (is it fast enough)
    • Fault tolerance (does it keep working)
  • Where in the system design does it help:
    • Ensuring completeness
    • Choosing interfaces
    • Devising implementations


  • INTERFACES are the critical piece of modularity, because it gives access to the components
    • Defines a language
      • Objects and operations
      • Nouns and verbs
    • States assumptions
      • If assumptions met, there are certain results and certain obligations
      • E.g. if you “open” a file, you must “close” it
    • The requirements of an interface are:
      • Simple as possible
      • Complete
      • Admits a small and fast implementation
  • SIMPLICITY – good game to play
    • Do one thing at a time (and do one thing well)
    • Don’t generalize – as simple as possible
      • Minimize cost, complexity
      • E.g. PL/I, general operations across data types were overly complex, never got the compiler correct, because of trying to generalize across all data types
    • Combining functionality causes dramatic increase in complexity
    • At one time, extra effort for speed paid off, BUT you need:
      • Knowledge of existing uses
      • Deep experience
    • Get it right – right abstraction… FindIthField
    • Make it fast (80/20 rule – get 80% of what you need for 20% of the work)
    • Don’t hide power – don’t bury it in generality
      • Example – Alto
    • Use procedure arguments
    • Leave it to the client – provide the building blocks (legos), and let the clients (users of your pieces) build the bigger picture
      • Separation of power
      • Monitor – client can do work without worrying about synchronization (via semaphores – P and V, critical sections)


  • CONTINUITY - Tension between improving design versus stability or continuity
    • Keep basic interfaces stable – do not let people subvert the facades
      • Interfaces embody assumptions, shared across a system
    • Keep a place to stand
      • Upward compatibility -
      • Compatiblity packages – implementing an old interface on top of a new system
      • Bootstrapping
    • Plan to throw one away (Brooks)… you will anyway
      • Costs less if you plan to throw away
      • Sometimes, two prototypes are neded
      • Revisit old design decisions
    • Keep secrets – balance interface implementation
      • Hide assumptions in implementation
      • Fewer shared assumptions – easier maintenance
      • Tension – increased efficiency (shared assumption) versus stability (hidden assumptions)
    • Divide and Conquer
      • Recursively or iteratively
    • Use a good idea again and again (no pride)
      • Replicate data
      • Operations on all objects (common interface versus common implementation)… things look the same, that aren’t
    • Normal versus abnormal scenarios – handle separately
      • Normal cases – handle quickly
      • Abnormal (worst) – make progress
  • SPEED – need to know what is appropriate, there are many techniques
    • Split resources – rather than sharing; allocated dedicated resources
    • Use static analysis – for speed and for correctness, for finding bugs
    • Interpretation (dynamic translation) – P-code, Java
    • Cache answers
    • Use hints
    • When in doubt, use brute force
    • Use background
    • Use batch processing
    • Safety first – stability before performance
    • Shed load
  • FAULT TOLERANCE – consider it early
    • End-to-end
      • Forward recovery
      • Backward recovery
    • Log updates (to allow rollback)
    • Make actions atomic or restartable – “idempotent” (?)



Post Development (assuming customization is part of development)

-          configure

-          release

-          install

-          update

-          reconfigure

-          de-install

** involves careful coordination and interaction of multiple producers and multiple consumers, often geographically and organizationally distributed


Typical Problems

-          information not available, complete, accurate

-          if available, not information for automation

-          tools are ad-hoc – scripts,

-          information not standardized

-          lack explicit dependencies, often lack needed context

-          context needs more than Ax on a CD-ROM

o        plug in memory

o        incompatible phased component


Current State

-          configuration and installation = best supported

-          other activities not at all

-          heavily context/environment dependent

-          no standard way to upgrade automatically





Some things will be paper-specific, lecture-specific


Covering Software Requirements, Design, some Architecture, some Deployment


T/F are mean, tricky


Multiple choice – sometimes 1-all answers are correct, points lost for wrong answers, missed right answers.


Essays – legible, decipherable, do not have to be complete sentences, can be phrases



One way that Garlan etc propose solving architectural mismatch

-          break things into smaller components that can be built in different way

-          have those components be orthogonal, without inherent assumptions about control

-          conflict-free components


Is this achievable?  Somewhat – not for all assumptions – e.g. if two components use two different data models then we have to build them separately, not orthogonally.