Without understanding programming in the large, one cannot understand the importance
of OOP
Intro OOP, Chapter 3, Slide 2
Programming in the Small and Programming in the Large
Programming in the Small:
-
One programmer, understands everything from top to bottom.
-
Major problem is the development of algorithms.
Programming in the Large:
-
System is developed by large team of programmers
-
Major problems are management of details and communication between
programmers and between their respective software subsystems.
Intro OOP, Chapter 3, Slide 3
Basis for Design
Consider for the moment what aspects of a problem are known first:
-
Data Structures
-
Functions
-
A Formal Specification
-
Behavior
A design technique based on behavior can be applied from the very beginning
of a problem, whereas techniques based on more structural properties
necessarily require more preliminary analysis.
Intro OOP, Chapter 3, Slide 4
Responsibility Driven Design
A design technique that has the following properties:
-
Can deal with ambiguous and incomplete specifications.
-
Naturally flows from Analysis to Solution.
-
Easily integrates with various aspects of software development.
Intro OOP, Chapter 3, Slide 5
Directed Evolution
Let us take specifications as they occur in nature
-
Imprecise
-
Ambiguous
-
Unclear
and rather than attempt to change human nature, let us direct the
evolution of the specification in concert with the design of the
software system.
Intro OOP, Chapter 3, Slide 6
An Example, the IIKH
Imagine you are the chief software architect in a major computing firm.
The president of the firm rushes into your office with a specification for the
next PC-based product. It is drawn on the back of a dinner napkin.
Briefly, the Intelligent Interactive Kitchen Helper will replace the
box of index cards of recipes in the average kitchen.
Intro OOP, Chapter 3, Slide 7
Your Job
Your job is to develop the software that will implement the IIKH.
Intro OOP, Chapter 3, Slide 8
Abilities of the IIKH
Here are some of the things a user can do with the IIKH:
-
Browse a database of recipes
-
Add a new recipe to the database
-
Edit or annotate an existing recipe
-
Plan a meal consisting of several courses
-
Scale a recipe for some number of users
-
Plan a longer period, say a week
-
Generate a grocery list that includes all the items in all the menus for a
period
Intro OOP, Chapter 3, Slide 9
Characterization by Behavior
Just as an Abstract Data Type is characterized more by behavior than by
representation, the goal in using Responsibility Driven Design will be to
first characterize the application by behavior.
-
First capture the behavior of the entire application.
-
Refine this into behavioral descriptions of subsystems.
-
Refine behavior descriptions into code.
This emphasis on behavior is a hallmark of Object-Oriented programming.
Intro OOP, Chapter 3, Slide 10
Working Through Scenarios
Because of the ambiguity in the specification, the major tool we will use
to uncover the desired behavior is to walk through application scenarios.
Other authors use the term ``use-cases'' for this process of developing
scenarios.
Intro OOP, Chapter 3, Slide 11
Software Components
A software component is simply an abstract design entity with which we
can associate responsibilities for different tasks.
May eventually be turned into a class, a function, a module, or something
else.
-
A component must have a small well defined set of responsibilities
-
A component should interact with other components to the minimal extent possible
Intro OOP, Chapter 3, Slide 12
CRC Cards
Components are most easily described using CRC cards. A CRC card records
the name, responsibilities, and collaborators of an component.
-
Inexpensive, Erasable, Physical
Intro OOP, Chapter 3, Slide 13
The first component, The Greeter
Let us return to the development of the IIKH. The first component your team
defines is the Greeter. When the
application is started, the Greeter
puts an informative and friendly welcome window (the greeting) on the screen.
Offer the user the choice of several different actions
-
Casually browse the database of recipes.
-
Add a new recipe.
-
Edit or annotate a recipe.
-
Review a plan for several meals.
-
Create a plan of meals.
Many of the details concerning exactly how this is to be done can be
ignored for the moment.
Intro OOP, Chapter 3, Slide 14
The Recipe Database Component
Ignoring the planning of meals for the moment, your team elects to next
explore the recipe database component.
-
Must Maintain the Database of recipes.
-
Must Allow the user to browse the database.
-
Must permit the user to edit or annotate an existing recipe.
-
Must permit the user to add a new recipe.
Intro OOP, Chapter 3, Slide 15
The Who/What Cycle
As we walk through scenarios, we go through cycles of identifying
a what, followed by a who
- What action needs to be performed at this moment,
- Who is the component charged with performing the action
Every what must have a who, otherwise it simply will not happen.
Sometimes the who might not be obvious at first, i.e., who should
be in charge of editing a recipe?
Intro OOP, Chapter 3, Slide 15a
Postponing Decisions
Many decisions, such as the method of browsing, can be ignored for the
moment, as they are entirely encapsulated within the recipe database component,
and do not effect other components.
-
Scroll bars and windows?
-
A virtual ``book'' with thumb-holes and flipping pages?
-
Keywords and phrases?
Only need to note that somehow the user can manipulate the database to
select a specific recipe.
Intro OOP, Chapter 3, Slide 16
Responsibilities of a Recipe
We make the recipe itself into an active data structure. It maintains
information, but also performs tasks.
-
Maintains the list of ingredients and transformation algorithm.
-
Must know how to edit these data values.
-
Must know how to interactively display itself on the output device.
-
Must know how to print itself.
-
We will add other actions later (ability to scale itself, produce integrate
ingredients into a grocery list, and so on).
Intro OOP, Chapter 3, Slide 17
The Planner Component
Returning to the greeter, we start a different scenario. This leads to the
description of the Planner.
-
Permits the user to select a sequence of dates for planning.
-
Permits the user to edit an existing plan.
-
Associates with Date object.
Intro OOP, Chapter 3, Slide 18
The Date Component
The Date component holds a sequence of meals for an individual date.
-
User can edit specific meals.
-
User can annotate information about dates (''Bob's Birthday'', ``Christmas
Dinner'', and so on).
-
Can print out grocery list for entire set of meals.
Intro OOP, Chapter 3, Slide 19
The Meal Component
The Meal component holds information about a single meal.
-
Allows user to interact with the recipe database to select individual
recipes for meals.
-
User sets number of people to be present at meal, recipes are automatically
scaled.
-
Can produce grocery list for entire meal, by combining grocery lists from
individual scaled recipes.
Intro OOP, Chapter 3, Slide 20
The Six Components
Having walked through the various scenarios, you team eventually decides
everything can be accomplished using only six software components.
You can at this point assign the different components to different
programmers for development.
Intro OOP, Chapter 3, Slide 21
Interaction Diagrams
The picture on the previous slide captures static relationships,
but not the dynamic flow of messages in a senario. That information
can be recorded by an interaction diagram.
Intro OOP, Chapter 3, Slide 21a
Characteristics of Components
Let us return to the idea of a software component.
There are many different aspects to this simple idea, we will consider
just a few:
-
Behavior and State
-
Instances and Classes
-
Coupling and Cohesion
-
Interface and Implementation
Intro OOP, Chapter 3, Slide 22
Behavior and State
All components can be characterized by two aspects:
-
The behavior of a component is the set of actions a component
can perform. The complete set of behavior for a component is
sometimes called the protocol.
-
The state of a component represents all the information
(data values) held within a component.
Notice that it is common for behavior to change state. For example,
the edit behavior of a recipe may change the preparation instructions,
which is part of the state.
Intro OOP, Chapter 3, Slide 23
Instances and Classes
We can now clarify a point we earlier ignored. There are likely
many instances of recipe, but they will all behave
in the same way. We say the behavior is common to the class Recipe.
Since earlier our goal was to identify behavior, we ignored this
distinction and concentrated on prototypical objects.
Intro OOP, Chapter 3, Slide 24
Coupling and Cohesion
The separation of tasks into the domains of different components should be
guided by the concepts of coupling and cohesion.
-
Cohesion is the degree to which the tasks assigned to a component seem to
form a meaningful unit. Want to maximize cohesion.
-
Coupling is the degree to which the ability to fulfill a certain
responsibility depends upon the actions of another component. Want to
minimize coupling.
Intro OOP, Chapter 3, Slide 25
Interface and Implementation
We have characterized software components by what they can do.
The user of a software component need only know what it does,
not how it does it.
``Ask not what you can do to a data structure,
ask instead what your data structures can do for you''.
Intro OOP, Chapter 3, Slide 26
Two views of a Software System
This naturally leads to two views of a software system.
The term information hiding is used to describe the purposeful
hiding of implementation details
Intro OOP, Chapter 3, Slide 27
Parnas' Principles
These ideas were captured by computer scientist David Parnas in a pair of
rules, which are known as Parnas' Principles:
-
The developer of a software component must provide the intended user with
all the information needed to make effective use of the services provided
by the component, and should provide no other information.
-
The implementor of a software component must be provided with all the
information necessary to carry out the given responsibilities assigned to
the component, and should be provided with no other information.
Intro OOP, Chapter 3, Slide 28
Public and Private View
In C++ and Java, Parnas's Principles lead to the ideas of a public and private view.
-
Public view - those features (data or behavior) that other components can
see and use
-
Private view - those features (data or behavior) that are used only
within the component
Intro OOP, Chapter 3, Slide 29
Next Step - Formalize the Interface
The next step is to formalize the channels of communication between the
components.
-
The general structure of each component is identified.
-
Components with only one behavior may be made into functions.
-
Components with many behaviors are probably more easily implemented as classes.
-
Names are given to each of the responsibilities - these will eventually be
mapped on to procedure names.
-
Information is assigned to each component and accounted for.
-
Scenarios are replayed in order to ensure all data is available.
Intro OOP, Chapter 3, Slide 30
A Rose by any other Name
Government bureaucrats have long shown us that obscure and idiomatic names
can make even the simplest operation sound intimidating.
The selection of names is an important task.
-
Names should be evocative in the context of the problem.
-
Names should be short.
-
Names should be pronounceable (read them out load).
-
Names should be consistent within the project.
-
Avoid digits within a name.
Intro OOP, Chapter 3, Slide 31
Documentation
Besides CRC cards, it is important that the development of other
documentation be performed almost from the beginning.
The two most important documents are the user manual and the design
documentation of the software system.
Intro OOP, Chapter 3, Slide 32
User Manual
The user manual describes the application as seen by the user.
-
Does not depend upon the implementation, so can be developed before the
implementation.
-
Can naturally flow from the process of walking through scenarios.
-
Can be carried back to the clients to make sure the users and the
implementors have the same ideas.
Intro OOP, Chapter 3, Slide 33
Quality
You should always remember that the primary measure of quality is the
degree to which your customers (clients) are satisfied with your product.
Since often customers do not know exactly what it is they want, it is
important to work with the client early in the design phase to make sure
the system your are developing is the desired product. One very important
way to do this is to create the user manual even before the software is
written.
Intro OOP, Chapter 3, Slide 34
System Design Documentation
Record the decisions made during the process of system design.
-
Record the arguments for and against any major decision, and the factors
influencing the final choice.
-
Record CRC cards for the major components.
-
Maintain a log or diary of the process schedule.
-
Important to produce this while the ideas are fresh, not in hindsight when
many details will have been forgotten.
-
Note the code only records the outcome of decisions, not factors that
lead up to decisions being made.
Intro OOP, Chapter 3, Slide 35
Preparing for Change
Your design team should also keep in mind that change is inevitable.
Users requirements change with experience, hardware changes, government
regulations change.
-
Try to predict the most likely sources of change, and isolate the effect.
Common changes include interfaces, file formats, communication protocols.
-
Isolate interfaces to hardware that is likely to change.
-
Reduce dependency of one software component on another.
-
Keep accurate record of the reasoning behind every major decision in the
design documentation.
Intro OOP, Chapter 3, Slide 36
Next Step - Select Representations for Subsystems
Next the internal representation of the software subsystem corresponding to
each component is selected.
Knowledge of the classic data structures of Computer Science is important
here.
Often once data structures have been selected, the code is almost
self-evident.
Intro OOP, Chapter 3, Slide 37
Step - Implement and Test Subsystems
Classic techniques, such as stepwise refinement, are used to
implement each of the subsystems.
Subsystems are validated in isolation.
-
Informal proofs of correctness for the subsystem are developed.
-
Identify necessary conditions for correct functioning.
Try to minimize conditions, and test input values whenever possible.
-
Software testing is used as a confidence building measure.
Intro OOP, Chapter 3, Slide 38
Step - Integration and Testing
Components are slowly integrated into completed system.
Stubs can be used to perform testing all during integration.
Errors discovered during integration to cause reinvestigation of validation
techniques performed at the subsystem level.
Intro OOP, Chapter 3, Slide 39
Maintainence and Evolution
Software does not remain fixed after the first working version is released.
-
Errors or bugs can be discovered. Must be corrected.
-
Requirements may change. Say as a result of government regulations,
or standardization among similar products.
-
Hardware may change.
-
Users expectations may change. Greater functionality, more features.
Often as a result of competition from similar products.
-
Better documentation may be required.
A good design recognizes the inevitability of change, and plans an
accommodation for these activities from the very beginning.
Intro OOP, Chapter 3, Slide 40
Common Design Flaws
The following categories present some of the more common design flaws:
Direct modification
Components that make direct modification of data values in other components
are a direct violation of encapsulation.
Such coupling makes for inflexible designs.
Too Much Responsibility
Components with too much responsibility are difficult to understand and to use.
Responsibility should be broken into smaller meaningful packages and
distributed.
No Responsibility
Components with no responsibility serve no purpose.
Often arise when designers equate physical existence with logical design
existence.
``Money is no object''
Components with unused responsibility
Usually the result of designing software components without thinking
about how they will be used.
Misleading Names
Names should be short and unambiguously indicate what the responsibilities
of the component involve.
Intro OOP, Chapter 3, Slide 41
This slide completes the material from Chapter two.