OO programming and design have their roots in simulation.
Simula (1967) programming language introduced objects & classes to describe the physical world being simulated.
The history of programming languages and of design can be viewed as a continual contest against increasing complexity of software systems:
Problem: too many … | Response | Useful? |
---|---|---|
… statements | nesting ( { … } ) | OK |
gather statements into functions | OK | |
… functions | nesting | inadequate |
gather functions into subsystems / “modules” | Too loosely defined | |
gather functions into encapsulated ADTs | Good | |
… ADTs | Gather into namespaces/packages | Not much help |
Organize loosely into inheritance hierarchies | The OO approach |
Observations
The most fundamental design technique
Start with a single statement describing the desired behavior
Automating book handling in a library:
Might start by dividing the system into major subsystems such as RecordStorage
, CheckInOut
, AccountMgmt
, and InventoryMgmt
.
Under each subsystem, you would group functions to be performed, such as
CheckOutBook
, CheckInBook
, and RenewBook
under the CheckInOut
subsystem, oraddBook
, removeBook
, and transferToBranch
under InventoryMgmt
.Getting Started
Suppose we wanted to design the function to add a new book to the library’s collection.
Designers would try to write out the simplest set of abstract steps that match their idea of what it means to “add a book”.
For the purposes of this example, they might reason that this function must both update the electronic card catalog so that the book can be found, and must also record that the book is present in the inventory of a particular branch.
Expressed as pseudocode:
function addBook (book, branchName)
{
bookInfo = getBookInfo(book);
record branchName as location in bookInfo;
addToCardCatalog (bookInfo);
addToInventory (bookInfo, branchName);
}
Next the designers would pick one of those rather vaguely understood lines of code in that function body and expand it, either in place or as a separate function. For example:
function addBook (book, branchName)
{
bookInfo = getBookInfo(book);
record branchName as location in bookInfo;
// addToCardCatalog (bookInfo)
add to AuthorIndex (bookInfo);
add to SubjectIndex (bookInfo);
add to TitleIndex (bookInfo);
cardCatalog.addToAuthorIndex
addToInventory (bookInfo, branchName);
}
The crucial idea here is that these new lines, taken together, add up to a method of achieving this line, the one we chose to expand.
We are not simply adding code. We are refining or expanding an abstract step into a series of somewhat more detailed ones.
If you, or another reader, do not believe that these lines add up to a procedure for achieving this line, then its time to stop and gp back. You’re doing something wrong.
Moving on, we would againpick a vaguely understood line and expand it.
function addBook (book, branchName)
{
bookInfo = getBookInfo(book);
record branchName as location in bookInfo;
// addToCardCatalog (bookInfo)
// add to AuthorIndex (bookInfo);
authorList = bookInfo.getAuthors();
for each author au in authorList {
catalog.authorIndex.addByAuthor (au, bookInfo);
}
add to SubjectIndex (bookInfo);
add to TitleIndex (bookInfo);
cardCatalog.addToAuthorIndex
addToInventory (bookInfo, branchName);
}
Stepwise refinement was certainly not the only pre-OO design technique, though it was probably the best known and most widely used.
However, nearly all pre-OO design approaches focused on behavior and functionality and on how to break those down into smaller pieces.
And that remained a problem, because ADTs are not so much about breaking behavior down as they are about gathering related behaviors together.
In this example, we have mentioned nearly a dozen functions. None of them have been associated with an ADT.
An experienced designer might spot some ADT candidates: Book, BranchLibrary, CardCatalog, etc.
But there’s nothing in the step-wise refinement process that encourages or supports this.
When we move to Object Oriented Analysis and Design, our challenge will be to move the ADTs to the front of the process, to shift the focus away from functions and towards the data.
Does this men that we will never worry about designing single functions? No, of course not. ADTs have function members, and those will eventually need to be designed. But the emphasis will be on getting the ADTs first, and then starting on the design of the individual function members.