Abstract systems
-- design methodology
- abstract system = abstract data types + protocol
Events
-- high level glue
- realization of the interaction protocol
}
The idea underlying the notion of
an abstract system is to collect
the commands available for the client
or user of the system.
The collection of commands comprising
an abstract system are usually
a (strict) subset of the commands
available in the combined interface
of the abstract data types involved.
In other words, an abstract system
provides a restricted interface,
restricted to safeguard the user
from breaking the protocol of interaction
implicitly defined by the collection
of abstract data types of which the system consists.
\c{
An abstract system in itself merely provides
a guideline on how a collection of objects is to be used,
but does not offer a formal means to check whether
a user plays by the rules.
After presenting an example of an abstract
system, we will look at how events
may be used to protect the user against breaking
the (implicit) laws governing the interaction.
}
Example -- the library
The abstract system comprising a library may be characterized as
in slide [3-library].
In essence, it provides an exemplary interface, that is,
it lists the statements that are
typically used by a client of the library software.
We use typical identifiers to denote objects
of the various types involved.
Abstract system -- exemplary interface
p = new person();
b = new book();
p = b->borrower;
s = p->books;
tf = b->inlibrary();
b->borrow(p);
p->allocate(b);
p->deallocate(b);
b->_return(p);
The commands available to the user of the
library software are constructors for a person
and a book,
an instruction to get access to the borrower
of a particular book, an instruction to ask what books
a particular person has borrowed,
an instruction to query whether a particular book
is in the library,
and instructions for a person to borrow or return a book.
To realize the abstract system library,
we evidently need the classes book and person.
The class book may be defined as in slide [3-book].
class book { \fbox{book}
public:
person* borrower;
book() {}
void borrow( person* p ) { borrower = p; }
void _return( person* p ) { borrower = 0; }
bool inlibrary() { return !borrower; }
};
\c{
It consists of a constructor, functions to borrow
and return a book, a function to test
whether the book is in the library
and an instance variable containing the borrower of the book.
Naturally, the class book may be improved
with respect to encapsulation
(by providing a method to access the borrower)
and may further be extended to store additional
information, such as the title and publisher of the book.
}
\slide{3-person}{The person class}{\slilarge
class person { \fbox{person}
public:
person() { books = new set(); }
void allocate( book* b ) { books->insert(b); }
void deallocate( book* b ) { books->remove(b); }
set* books;
};
}
\c{
The next class involved in the library system
is the class person, which is shown in slide [3-person].
The class person offers a constructor,
an instance variable to store the set of books borrowed
by the person and the functions allocate and deallocate
to respectively insert and remove the books
from the person's collection.
A typical example of using the library system is given below.
}
\nslide{}{}{
book* Stroustrup = new book();
book* ChandyMisra = new book();
book* Smalltalk80 = new book();
person* Hans = new person();
person* Cees = new person();
Stroustrup->borrow(Hans);
Hans->allocate(Stroustrup);
ChandyMisra->borrow(Cees);
Cees->allocate(ChandyMisra);
Smalltalk80->borrow(Cees);
Cees->allocate(Smalltalk80);
}
First, a number of books are defined,
then a number of persons,
and finally (some of) the books that are borrowed
by (some of) the persons.
Note that lending a book involves
both the invocation of
and .
This could easily be simplified by extending the function
and
with the statements
and respectively.
However, I would rather take the opportunity to illustrate the use
of events, providing a generic solution
to the interaction problem noted.
Events
[Henderson93] introduces events
as a means by which to control the complexity of relating
a user interface to the functionality provided
by the classes comprising the library system.
The idea underlying the use of events is that for
every kind of interaction with the user
a specific event class is defined that captures
the details of the interaction between the user
and the various object classes.
Abstractly, we may define an event as an entity
with only two significant moments in its life-span,
the moment of
its creation (and initialization)
and the moment of its activation
(that is when it actually happens).
As a class we may define an event as in slide [3-event].
\slide{3-event}{The Event class}{
class Event { \fbox{\fbox{Event}}
public:
virtual void operator()() = 0;
};
}
\c{
The class Event is an abstract class,
since the application operator that may
be used to activate the event is defined as zero.
}
\slide{3-borrow}{The Borrow event class}{\slilarge
class Borrow : public Event { \c{\fbox{Borrow}}
public:
Borrow( person* _p, book* _b ) { _b = b; _p = p; }
void operator()() {
require( _b && _p ); \c{// _b and _p exist}
_b->borrow(p);
_p->allocate(b);
}
private:
person* _p; book* _b;
};
}
\c{
For the library system defined above we may conceive of two
actual events (that is, possible refinements
of the Event class),
namely a Borrow event and a Return event.
See slides [sli-3-borrow] and [sli-3-return].
}
\c{
The Borrow event class provides a controlled
way in which to effect the borrowing of a book.
In a similar way, a Return event class may be defined
as in slide [3-return].
}
\slide{3-return}{The Return event class}{
class Return : public Event { \c{\fbox{Return}}
public:
Return( person* _p, book* _b ) { _b = b; _p = p; }
void operator()() {
require( _b && _p );
_b->_return(p);
_p->deallocate(b);
}
private:
person* _p; book* _b;
};
}
\c{
The operation Has specified in the
previous section has an immediate counterpart
in the data member and need
not be implemented by a separate event.
}
\c{
Events are primarily used
as intermediate between the user (interface)
and the objects comprising the library system.
For the application at hand, using events
may seem to be somewhat of an overkill.
However, as we will further illustrate
in section [events],
events not only give a precise characterization of
the interactions involved but, equally as important,
allow for extending the repertoire
of interactions without disrupting
the structure of the application
simply by introducing additional event types.
}
introduction
teaching
contracts
patterns
events
examples
foundations
conclusions
references