CS320 Lecture: Object-Oriented Design 8/27/96 revised 9/5/97
revised 8/5/99
Materials: Transparencies: List of objects for ATM system
Class diagram for ATM system
Filled in Class Description Form for Bank
Filled in Operation Description Form for
Bank::initiateWithdrawl
CRC Card/Class Description Form for Session
Handouts: ATM example CRC cards
ATM example Class Diagram
Other: Supply of 4x6 cards for CRC cards
Supply of Class Description Forms (1 each)
Supply of Operation Description Forms (3 each)
(+ online versions of latter two)
Example of OOA/OOD/OOP (ATM) available on Web
Executable version of ATM demo
I. OO Design
- -- ------
A. At the start of our discussion of OO analysis, we saw that software
development projects entail a series of tasks, beginning with analysis.
The next major step in the process is design.
1. The goal of analysis is to UNDERSTAND the system - i.e. to decide
WHAT is to be built.
2. The goal of design is to STRUCTURE the system - i.e. to decide HOW
it is to be built.
B. In traditional software development methodologies, the line between
analysis and design is fairly sharp, because very distinct notations are
used for documentation at each stage. In OO methodologies, the line is
less distinct, because similar notations can be used at both stages.
In fact, we will learn two notations under the heading of design that
can actually be considered analysis tools as well, since both sit right
at the boundary between analysis and design.
1. CRC cards (Class, Responsibility, Collaborator)
2. Class diagrams
In fact, the seamlessness of OO tools at the transitions between the
various phases of the software lifecycle is a strength of the OO
paradigm
(We will also be looking at some tools that are explicitly for design:
Class Description Forms and Operation Description Forms.)
C. The analysis phase of the development effort should have identified the
key objects needed for the system. We now need to accomplish the
following:
1. Develop the class structure for the system i.e.
a. Identify the classes to which the various objects should belong.
b. Identify relationships between various classes
2. Design the various classes. For each class, we must determine:
a. Attributes comprising the state of objects of that class.
b. Operations that can be performed by objects of that class.
3. Since large systems may include hundreds or thousands of classes,
some partitioning of classes into subsystems (modules) is often
necessary.
D. As we do the design, we will often discover the need for additional
objects and classes, to facilitate the implementation of the objects we
discovered during analysis.
II. Developing and Documenting the Class Structure
-- ---------- --- ----------- --- ----- ---------
A. A task which lies on the border between analysis and design is that of
identifying the CLASSES that the objects comprising the system will
belong to, and then determining how these classes RELATE to each other.
1. We can start by taking advantage of the fact that every object we
discovered during analysis will turn out to be an instance of some
class (though several could, of course, be instances of the same
class.)
Example: TRANSPARENCY OF OBJECTS PREVIOUSLY DISCOVERED FOR ATM
IDENTIFY CLASSES - LIST ON BOARD
(Note naming convention - single token, UC letter at start and
for beginning of new word)
LEAVE LIST ON BOARD FOR NEXT PART
NOTE: Not every item on this list will end up in our final design
2. However, working out the best class structure is a non-trivial
process that involves considerable effort, as well as making choices
among alternatives and sometimes revisiting and revising those
choices as the design develops.
B. One tool that we can use to help us do this (and actually also to
identify objects as well) is called CRC Cards (CLASS, RESPONSIBILITY,
COLLABORATOR).
1. A CRC card is a card (generally about 4 x 6) containing at the
top the name of a class, followed by two parallel lists.
a. The list on the left hand side lists the RESPONSIBILITIES of
the class.
b. The list on the right hand side lists the other classes (if any)
with which this class must COLLABORATE to carry out each task.
c. As noted in the book, the back can be used for listing class
attributes - though we will handle this in another way.
2. A typical way to use CRC cards is to "walk through" the various
functions of the system, assigning responsibilities for each operation
to an appropriate class and identifying other classes that need to
collaborate in this task, and then noting this on the card.
a. Earlier, we say that nouns occurring in the problem description
often refer to objects. Now, we want to focus on the VERBS,
which often describe OPERATIONS PERFORMED BY SOME OBJECT.
b. The key question to ask for each operation is "what class should be
responsible for this?"
c. Often there will be more than one possible answer, so the
different alternatives need to be examined carefully before a
choice is made.
d. This process lends itself particularly well to a group of people
working together, with individual members of the group role-playing
various classes. (Remember, in an OO system the basic
computational model is one of different objects sending messages
to each other.)
3. EXAMPLE: Walk through session use case. Draw CRC cards on board as
they get filled in.
NOTE AT OUTSET: There is no one best way to make the responsibility
assignments. I made certain choices in developing the example, and
we will work with those so that everything hangs together.
(Actually, I did some fine tuning of the design during the
implementation phase, and the approach we will take reflects that.
The fine tuning resulted in a more modular design with less coupling
between classes)
a. "A session is started when a customer inserts an ATM card into
the card reader slot of the machine, which reads the card as it
is inserted ..."
i. What class should be responsible for starting a session when
the card is inserted?
ASK - be sure to get both ATM and CardReader
ASK - why wouldn't Session be appropriate here? (Session
object doesn't get created until this occurs)
ASK - which class should we choose?
- Assume ATM
ii. What class(es) does ATM need as collaborators for this task?
ASK - be sure to get:
Display (for message telling user to insert card,
plus message about an unreadable card),
CardReader(to tell us when card is inserted),
Session (a Session instance is created when the card
is successfully inserted)
iii. Enter the above on card for ATM
iv. What other classes get responsibilities as a result of this?
ASK - CardReader must recognize card inserted and either read
it or report it unreadable
Display must display "insert card" and "unreadable
card" messages.
Session does NOT get any responsibilities - it just
gets created!
Enter the above on cards for CardReader, Display
b. We will make Session itself responsible for performing the
rest of the session use case, once the case is started by ATM
creating a Session object.
PUT ON CARD
At each step along the way, it will call on other classes to
perform the various steps.
c. "the customer is asked to enter his/her PIN"
i. What class(es) will Session call on to do this? - ASK
Possible answers: ATM, Keyboard
We will make ATM responsible, and let it, in turn, call on
the Keyboard to do the work. This will help to reduce the
coupling between classes.
ii. Collaborators for ATM? - ASK
(Display - for prompt)
(Keyboard - to read PIN)
-- and note that Keyboard also needs Display to echo asterisks
iii. Enter the above on cards for ATM, Display, Keyboard
d. "(The customer) is allowed to perform one or more transactions,
choosing the transaction type each time from a menu of options."
i. What class(es) will Session call on to do this?
Again - ATM to get desired type
Plus Transaction to actually do the work
ii. Collaborators for ATM? - ASK
(Display, Keyboard)
iii. Collaborators for Transaction? - ASK
(Subclasses: WithdrawlTransaction etc. They in turn will
call on other classes to get their job done)
iii. Enter the above on cards for Keyboard, Display, Transaction
e. The session will furnish the customer's card number and PIN to
each transaction.
i. Here Session picks up a responsibility, and will serve as
a collaborator for Transaction.
ii. Put on cards for Session, Transaction.
f. "After each successful transaction, the customer is asked whether
he/she would like to perform another"
i. What class(es) will Session ask to do this? - ASK
(ATM)
ii. Collaborators? - ASK
(Display, Keyboard)
iii. Enter the above on cards for ATM, Display, Keyboard
g. "When the customer is through performing transactions, the
card is ejected from the machine."
i. What class(es) will Session ask to do this?
Possibilities: ATM, CardReader
Again, for modularity we will make ATM responsible and let it
call on CardReader to do the work.
ii. Collaborators? - ASK
(CardReader)
iii. Enter the above on ATM, CardReader cards
4. Class Exercise:
DISTRIBUTE 4X6 CARDS
a. Break into teams
b. Assign each team a use case (from 4 transaction types, Invalid PIN)
c. Procedure: Assign each class to one person. (A given person may be
assigned more than one class). Act out the scenario, with the
person responsible for the currently active class holding up the
card and speaking for it - e.g. when the ATM is reading a PIN from
the Keyboard, the person responsible for the ATM card would hold it
up and say: "I need a PIN. Keyboard, read a PIN for me". Then the
person responsible for the Keyboard card would hold it up and say
"I am reading a PIN from the customer" ... As a consequence,
Keyboard would appear on the ATM card as a collaborator, and
"read a PIN" would appear on the Keyboard card as a responsibility.
d. Allow time, then have teams share results
5. HANDOUT - my CRC cards for ATM system - GO OVER
C. In order to be useful to us, the design that emerges from our analysis
and our work with use cases and CRC cards must be documented in some
suitable fashion. While CRC cards are a good tool for developing a
design, they do not serve well as a permanent documentation tool.
1. At this point, we are interested in documenting the class structure -
i.e. the classes that are part of our system and their RELATIONSHIPS.
The tool we are about to learn will help us do that.
2. Later, we will look at developing a detailed design for each class,
and will learn other tools for that purpose.
Actually, these tools will serve not only to help us to document our
design, but also to refine and clarify it in the process.
D. The tool that we are going to learn to use now is called a CLASS DIAGRAM.
As is often the case, "a picture is worth a thousand words".
1. TRANSPARENCY - CLASS DIAGRAM FOR ATM SYSTEM
2. Notation:
a. Over the years, a number of different sets of notation conventions
have been developed for class diagrams. (See pp. 98-99 in the
text.) Recently, a system of notation called the Unified Modelling
Language (UML) has come into broad acceptance in the OO community
for the whole spectrum of OO modelling, including class diagrams.
We will use this convention - a departure from prior years in which
this course was taught using the "Booch" conventions. Note that
our text basically uses UML as well, though it retains one feature
of the older Booch diagrams are kept. (BTW - Booch is one of three
people who collaborated on developing UML).
b. Classes are represented by boxes, with the name of the class inside.
The box for a class can also contain additional elements:
i. Attributes (or at leat the more important ones)
ii. Methods (or at leat the more important ones)
iii. Responsibilities (major ones from CRC cards)
For now, we will not include these in the diagram for the ATM
system, but we may include at least the responsibilities in other
examples.
c. Relationships between classes are represented by lines between
the classes. (We will talk about what each kind of relationship
is and how to discover these relationships shortly.)
i. There may be a triangle, arrow, or open or filled diamond at one
end of the relationship to indicate what sort of relationship
it is and the direction of the relationship.
- e.g. the triangle at Transaction on the lines connecting it to
Withdrawl Transaction, DepositTransaction. etc. indicates that
a Transaction is a generalization of the various specific
kinds of transactions. (Or, alternately, WithdrawlTransaction
is a specialization of Transaction, etc.) Note that the
triangle is connected to the MORE GENERAL class.
A generalization relationship can often be described by
using the phrase "is a" or "is a kind of" - a
WithdrawlTransaction is a (kind of) Transaction.
- e.g. the filled diamond at ATM on the lines connecting it to
CardReader, Display etc. indicates composition - an ATM is
composed of a CardReader, a Display, etc. Note the diamond
is connected to the COMPOSITE CLASS.
A composition relationship can often be described by using the
phrase "has a" or "has" - an ATM has a CardReader.
- e.g. the open diamond on the line between Session and
Transaction indicates aggregation - a Session is an aggregate
of Transactions., Note that the diamond is connected to the
AGGREGATE CLASS.
An aggregation relationship can also be described by using the
phrase "has a" or "has" - a Session has Transactions.
Note that composition and aggregation are very similar
concepts. The distinction is that with composition the
component parts have no existence outside of their owner -
with aggregation they might. (In this case, transactions
live on in the records of the bank even after the ATM session
where they were performed is terminated.)
- e.g. the associations without a triangle or diamond on them
indicate a more general "makes use of" relationship. (The book
labels these with an open circle, a feature borrowed from the
older Booch notation.) Sometimes these associations have an
arrowhead to indicate "navigabilty" - the fact that you can
get to one object from the other (e.g. one object knows about
the other), but not vice-versa - e.g.
- a Transaction uses the Bank, and so must know about it;
but the Bank does not necessarily have to know about the
Transactions (they announce their own arrival over the
network), so the arrow is from Transaction to Bank.
- The ATM knows about and uses the Bank, and vice versa - hence
no arrowheads. (Alternately, some writers would use
arrowheads both ways.)
ii. Numbers appear at both ends of some relationships to indicate
the CARDINALITY of the relationship - more on this later as well.
E. We said earlier that one important task is identifying RELATIONSHIPS
between classes, and we have now seen that these play a prominent
role in our class diagram notation. We need to be aware of several
possible kinds of relationships that can exist between classes:
1. One important relationship between classes we need to identify is the
"is a" or GENERALIZATION relataionship (sometimes called INHERITANCE).
When we have classes of objects that are similar, but not identical, we
may use a base class to capture their commonalities and derived
classes to capture their distinct features. This allows data and code
that is common to be re-used by all the derived classes.
a. Example: In the ATM system we have been discussing, we have noted
that a customer may perform a series of transactions of
various sorts: deposits, withdrawls, transfers, inquiries.
We can easily model this using a class hierarchy with a
base class "Transaction" and derived classes
"DepositTransaction", "WithdrawlTransaction" etc.
TRANSPARENCY: Note Transaction class hierarchy
b. Example: There is at least one other obvious class hierarchy in the
larger system of which the ATM is a part (though it won't
actually be directly a part of the example we are doing.)
ASK - The bank account class hierarchy
DEVELOP with class
c. In developing class hierarchies, we will deal with two kinds of
classes: CONCRETE CLASSES, and ABSTRACT CLASSES.
i. A concrete class is one where we will actually have objects in
the system that are instances of this class.
ii. An abstract class is one where all objects that are of that
class are actually instances of some subclass - none are
instances of that class alone.
Example: In the ATM system, we have identified several classes of
transactions - deposit transactions, withdrawl
transactions, etc. - which leads to a class hierarchy in
which each of these classes is derived from a base class
"transaction". This base class is abstract - there will
never be an object that represents a transaction that
is not of one of the specific types we have identified.
Example: Another abstract class in the overall system of which
the ATM is a part - ASK.
Bank account (all bank accounts are actually checking,
or savings ...)
Abstract classes are denoted in a class diagram by putting the
class name in italics. (Note Transaction in the example).
Alternately, the word abstract can appear in braces after the
class name - a somewhat more noticeable notation.
iii. It will not always be the case, however, that a base class is
abstract. Sometimes we create derived classes to model a
specialized subset of a general class of objects.
Example: The book developed an example based on a voice mail
system. One key class was Mailbox, with a subclass
AdminMailbox for the one special box belonging to the
system administrator (which can perform all the
functions of a regular mailbox plus special
administrative ones.
In this case, because the functions of AdminMailbox are
a strict superset of those of a Mailbox, it makes
sense for both classes to be concrete, with most
mailboxes instances of Mailbox and one of AdminMailbox.
iv. Sometimes, we distinguish between the related terms
"generalization" and "specialization" as follows: An ABSTRACT
BASE CLASS is a GENERALIZATION of its derived classes - i.e. the
set of instances of the base class is simply the union of the
set of instances of the derived classes. On the other hand, a
subclass of a CONCRETE BASE CLASS is said to be a SPECIALIZATION
of that class.
However, following the conventions of UML we will not normally
bother to make this distinction, lumping all "is" relationships
under the heading "gneralization".
d. In a Class diagram, an "is" relationship is denoted by an open
triangle pointing to the base class.
TRANSPARENCY - Transaction hierarchy
2. Another important relationship that arises between classes is
AGGREGATION/CONTAINMENT also known a "has a" or "part of".
a. A particular object may have one or more other objects as component
parts, or may contain one or more objects of some other kind.
i. Example: One kind of object that is part of an ATM system is the
machine itself. This object has other objects as component
parts - e.g. a card reader, a keyboard, a display, an
envelope acceptor, a cash dispenser, a receipt printer and
an operator switch.
ii. Example: An ATM session can be thought of as an aggregation of
transactions. Though this falls outside the scope of the
example system we are developing, we know that each account
object will also need to contain a list of all the transactions
performed on that account (including those done with a human
teller or by check) so that a monthly statement can be produced
- so it, too, is an aggregation of transactions, though of a
different sort.
b. UML draws a distinction between aggregation and composition, in
terms of whether the parts have an existence apart from the whole.
We use containment (denoted by a filled diamond) for the
relationship between an ATM and its component parts. We use
aggregation (denoted by a hollow diamond) for the relationship
between transactions and a session.
c. Note: that this relationship must be carefully distinguished from
the inheritance relationship we discussed earlier between classes.
i. An inheritance relationship exists when the phrase "is a" is
appropriate
Example: we can say "a customer is a person" - but we would not
say "a card read is an ATM"
ii. An aggregation relationship exists when the phrase "has a" or
"is a part of" is appropriate.
Example: we can say "an ATM has a card reader" or "a card reader
is part of an ATM" - but we would not say "a customer
is a part of a person"
iii. Note that the "has" relationship is first and foremost a
relationship between objects, while the "is a" relationship is
between classes. That is, the "is a" relationship between classes
gives rise to a CLASS HIERARCHY, while the "part of" relationship
between objects give rise to an OBJECT HIERARCHY. These are
two fundamentally distinct, but easily confused concepts.
Example: A keyboard is part of an ATM machine. But we wouldn't
have a keyboard class as a subclass of the ATM machine
class - there is no inheritance relationship present.
Example: A checking account is a bank account, which implies an
inheritance relationship between the checking account
class and the bank account class. However, an individual
checking account object does not have any relationship to
some other bank account object - it is, in fact, its own
bank account object. (In fact, in this case there will
probably not be any objects that are simply bank accounts
- each account will in fact be some particular type such
as checking, savings, etc.)
d. One important characteristic of a "has" relationship is its
CARDINALITY.
i. Example: An ATM normally has exactly one card reader, and each
reader etc. is associated with one ATM.
The relationship between an ATM and its card reader is
1:1.
ii. Example: A bank account can have any number of deposits made to
it during a given month, but each deposit is made to one
specific account.
The relationship between accounts and deposits is 1:n.
iii. Example: Each ATM card is tied to a specific set of accounts it
can access (usually at most one of each kind - e.g.
at most one checking, at most one savings, etc.). A
given account may be accessible through more than one
card.
The relationship between ATM cards and accounts they
can access is m:n.
e. In a Class diagram, these cardinalilities can be denoted by numbers
on each end of the line.
TRANSPARENCY: Relationship of ATM to its various parts - note
that, in this case, all are 1:1.
TRANSPARENCY: Relationship of ATM to Session is 1:*, and between
Session and Transaction is 1:*. The * denotes "0 or
more". (A Session could have 0 Transactions if it
is aborted for some reason, and an ATM might not ever
be actually used!)
The following forms are commonly used to record cardinalities:
1 - one and only one
0, 1 - optional: either none or at most one.
* - zero or more
1..* - one or more
More rarely: a specific integer - e.g. the relationship between
a soccer team and the players currently on the field
could have 11 on the players end - or specific range
of integers - e.g. the relationship between a Monopoly
game and its players could have 2..6 on the player end.
ASK CLASS FOR EXAMPLES OF
- A relationship that could be annotated 0,1
- A relationship that could be annotated 1..*
f. A special form of the contains relationship we will discuss in
more detail later is the notion of a CONTAINER CLASS. A container
class is typically a fairly generic class whose purpose is to
contain other objects - e.g. a list, or a table, or sometimes a
stack or a queue. When we get into detailed design of a class that
has a "has" relationship to another class, we may put a container
class in the middle.
Example: Our ATM as specified does not keep any electronic log
of the transactions it performs - i.e. once a transaction
is complete, the transaction object in the ATM can be
destroyed (though the bank may keep a similar object).
If we decided to keep an electronic log of transactions,
we might create a container class TransactionList, which
would store completed transactions in some appropriate
way (e.g. as a linked list.) The ATM itself would, in
turn, contain one instance of an object of this class to
hold its electronic log.
DRAW DIAGRAM - 1 ATM has 1 TransactionList has n Transactions
3. A third possible relationship between objects is AWARENESS/USING. A
particular object may need to be aware of another object and may need
to use the other object to help it accomplish its task.
a. Example: In the ATM system, a Transaction object uses the ATM (and
indirectly its components) to interact with the customer.
It also uses information from the Session object about
the customer's card number and PIN, and uses the Bank
to actually perform the transaction.
However, this is a distinct relationship from aggregation/
containment - neither the ATM nor the Session nor the Bank
is really "part of" the Transaction - in fact, these
objects existed before the Transaction object was created
and will continue to exist after it is destroyed.
b. Presumably any object that has/contains another object also uses it
in some way, but there are using relationships that do not involve
aggregation/containment, so we treat this relationship as distinct.
c. An awareness relationship can be either undirectional or
bidirectional.
i. An object A may be aware of object B (and utilize its services)
without object B having to be aware of object A (except in a
transitory way when providing a service.)
ii. Or, objects A and B may be mutually aware of each other, and
may utilize each others services.
ASK: Real world examples of each case.
d. This kind of relationship is very general, and can be used to
model any relationship between objects that is significant to the
problem.
e. Whereas recognition of "is a" and "has" relationships frequently
arises from domain analysis, "uses" relationships are often
discovered by use case analysis and/or the use of CRC cards, as we
see how the various objects interact with each other to meet the
functional requirements of the system. In particular, a class
uses each class that appears as a collaborator on its CRC card.
f. In a Class diagram, a uses relationship is indicated by a line
connecting the classes with an arrowhead at the "used" end
(if one directional) or no adornments at all (if bidirectional).
TRANSPARENCY: Note various uses relationships, some of which
are bi-directional
NOTE: Our text, following a form of pre-UML Booch notation, uses
an open circle for "uses" relationships.
4. One other possible relationship we'll note briefly now is that
the entire existence of one class may be hidden inside another.
(This is a form of usage for implementation, but now all knowledge
of the used class is restricted to the one using class.)
a. Example: suppose we were building a container class to hold lists
of other objects (e.g. a log of transactions.) When we
go to build the list, we might decide we need a node class
to hold the individual elements of the list - but this
class could be completely hidden inside the list class.
No one outside need ever see it.
DRAW DIAGRAM: Node class physically contained in box for a List
class.
b. Since the need for the very existence of such classes usually isn't
discovered until detailed design of the implementation of the using
class, we won't say more about this now.
5. Note, again, how relationships are documented on the class diagram.
TRANSPARENCY
a. Classes
b. Labelled relationships
c. Significance of triangles and open and filled diamonds,
d. Cardinality notation
III. Designing Individual Classes
--- --------- ---------- -------
A. The work we have done thus far has given us two sets of design
documents:
1. A set of CRC cards that identifies at least some of the
responsibilities for each of our classes.
2. A class diagram that shows the overall class structure, including
the inter-relationships of our classes.
B. We said earlier that CRC cards are very useful as a tool for discovering
a good design, but are not a good documentation tool.
1. Some of the information that was on the CRC cards has been
incorporated into our class diagram.
2. But the information about specific responsibilities still exists only
on the CRC cards, and needs to be documented more neatly and
fully.
C. Our next step, then, is to develop a detailed design for each of the
classes appearing in our class diagram, using the work we did on the
CRC cards. For this purpose, we will make use of Class Description
Forms and Operation Description Forms.
1. These forms were originally designed by Booch, who called them
"class templates" and "operation templates". (But the word template
has a different meaning in C++, so we will call them forms.)
2. Our text has a simplified version of these, which is what we will
use.
TRANSPARENCY: Filled in Class Description Form for Bank
TRANSPARENCY: Filled in Operation Description Form for
Bank::initiateWithdrawl
3. Creating Class Description Forms from CRC cards is relatively
simple
TRANSPARENY: CRC card and Class Description Form for Session
4. CLASS EXERCISE:
a. DISTRIBUTE: Blank Class Description Form (1 each) and Operation
Description Form (3 each)
b. Work through Class Description Form and Operation Description Forms
for CashDispenser class, working from CRC cards
5. Copies of these forms are available online as CS320:CLASS.FORM and
CS320:OPERATION.FORM
6. We will see, when we move to OO Programming in our next lecture, that
moving from forms like these to C++ code is a relatively straight-
forward process.
IV. Example ATM System on WWW
-- ------- --- ------ -- ---
A. Show how to access.
B. Show the following (class has already received)
1. Requirements
2. Use cases
3. Domain objects
4. CRC cards
5. Class Diagram
C. Links to material class has not yet seen
1. CRC Cards to Class Description Forms
2. Methods in class description to Operator Description Forms
3. For later: Both kinds of forms to C++ code
D. Demo executable
V. Additional Thoughts on Producing a Quality Design
- ---------- -------- -- --------- - ------- ------
A. The design phase of software development is one that is easy to rush,
because we have a tendency to want to "get on with the coding". But
time spent here to ensure we have done a quality job can greatly reduce
the time spent subsequently on implementation and maintenance. We look
now at some ideas and suggestions that can help make for quality design.
B. In chapter 6 (which you will read later), our book talks about the use
of CLASS INVARIANTS and PRECONDITIONS and POSTCONDITIONS for operations.
1. A class invariant is a property of each that is a member of the class
which is initially made true when the object is constructed, and is
preserved by all operations of the class.
Example (from the book): We may create a class to represent calendar
dates, with fields holding a year, month and
day. One desirable class invariant is that the
object always represents a valid date - i.e.
month must lie between 1 and 12 and day must
lie between 1 and an upper limit that is
determined by month (and possibly by year).
In designing the operations of the class, we want to ensure that they
can preserve the class invariant.
Example (from the book): We might not want to include an operation
setMonth in a date class because it could be
used to violate the class invariant. Even
if its argument lies between 1 and 12,
changing the month could make a formerly
valid day no longer valid (e.g. if the date
is 1/31 and we change the month to 2, we are
in trouble!)
2. You should already be familiar from CS122 with the idea of defining
preconditions and postconditions for operations. This can be done
for class methods, and should be done at least in some cases.
Example: The CashDispenser::dispenseCash method has a precondition
that the necessary money is on hand.
C. The association of invariants with classes, and preconditions and
postconditons with methods of classes, is known in the OO world as
PROGRAMMING BY CONTRACT.
Copyright ©1999 - Russell C. Bjork