Object oriented approach
Rob
Pooley
Managing complexity
Software
development is hampered by the complexity of large software systems
Software
engineering has developed techniques to manage this complexity
These
depend on hiding detail not essential to the task in hand
Such
an approach is known as abstraction
Functional abstraction
The
introduction of procedures and functions into programming languages supported
functional abstraction
A
procedure hides the detail of the sequence of operations needed to carry out a function
or operation
By
using procedures to build further new procedures, a hierarchical notion of
problem solving is allowed
bottom
up function composition
By
decomposing a problem into smaller functions a top down notion of problem
solving is used
top
down functional decomposition
Abstraction and architectures
The
software engineering approach to managing complexity
Parameterisation and scope
Procedures
define a local, protected area of memory
Parameters
allow values from outside to be transmitted to functions
This
combination allows a procedure call to generate a new, unique instance
of the procedure
Functions
allow values to be generated by procedure calls
Procedural encapsulation
If
we eliminate global data (accessible to all procedures) and pointers (indirect
access to non-local memory) procedural abstraction allows self-contained, safe
functional elements
This
view is powerful, but slower than unstructured approaches
The
cost of calling and parameter passing is a major overhead
Optimising
compilers seek to inline procedure calls
Data abstraction
An
second approach to abstraction is to hide the implementation of the information
being manipulated
This
allows complex information to be treated as a single structured value when used
as a whole
This
idea was probably first used in COBOL, where a data definition section was used
to define elaborate record formats
Data
abstraction is implicit in may file handling libraries
Pascal
used records, while C has structs
This
approach simplifies parameter passing and helps to keep data internally
consistent
Abstract data types
Combining
functional and data abstraction creates the concept of an abstract data type
(ADT)
The
stack is an classic example of an ADT
A
stack can be fully defined without providing an implementation
Its
definition is in terms of the operations it supports and some properties which
are always true about the stack (its invariants)
Axioms
The minimum set of rules which
fully and unambiguously define an ADT are called an axiomatic specification of
a stack
Other examples of ADTs are first
in first out queues and ordered lists
You might like to try to define a
full set of axioms for these
Software architectures
Software
design often uses an architecture to provide a very high level view of a system
This
allows an effective design to be shown simply
It
may also create inefficiency if the architecture is a poor one for the use it
is put to
Patterns
are an idea borrowed from physical architecture to present a solution in the
context where it is useful
A
typical approach is to think of a system as a set of communicating processes
Here
are a few examples of commonly used architectures
Software stack
Layers of functionality
Higher layers offer higher level
functionality
Typical example is a communication
protocol stack, such as those following the ISO 7 layer model
Not all applications need all the
layers
Layers may duplicate functions
Function versus efficiency
Shared memory
Several processes all have the
same memory locations accessible
This may be separate processors
sharing one block of memory
It may also be several logical
processes on the same processor
Where a controller uses a shared
buffer with a main processor it is referred to as direct memory access
the AGP port on a PC
Remote procedure call
When
one process requests an operation from another, it is usually expressed as if
it was a procedure call
Such
calls, which include the called process as a parameter, are known as remote
procedure calls (RPCs)
There
must be some protocol for passing such calls
In
object oriented systems this is known as remote method invocation (RMI)
Distributed memory
Physically separate processors
often use an interconnection network to pass information
Multi-processor computers often
use such a message passing architecture
Networks of workstations (NOW) can
be used similarly
Communication delay is the major
bottleneck in such cases
Each processor has its own memory
Other physical configurations
Logical versus physical configuration
The
performance of distributed memory systems depends on the number of hops and
crossings made by each message
Logical
channels are usually mimicked by a harness such as PVM or MPI, allowing
direct addressing between processing elements
The
actual physical organisation is hidden and can take several forms
Fault tolerant systems 1 - voting
Voting systems try to stop faults
crashing systems
Multiple versions of critical
components are created independently
When functions in these components
are invoked each votes on what should happen
The majority wins
Adds overheads of extra versions,
of forking and of voting
Fault tolerant systems 2 - exceptions
Critical functions can be
encapsulated in blocks
Any unwanted behaviour can result in
an exception being thrown
The exception can be caught in the
surrounding block
The exception handler can either
try an alternative
perform some correction
abort gracefully
Client/server
Objects and components
OO Review and the "Bigger
Picture"
Review of OO Concepts
and Terminology
There is more to OO
than C++: e.g.
Java's Interface Concept
CORBA's IDL
OO Programming vs OO
Design vs OO Analysis
Putting Things in
Context: The Bigger Picture
What is an object?
Something you can do
things to. An object has state, behaviour and identity;
the structure and behaviour of similar objects are defined in their common
classes. The terms instance and object are interchangeable.
(From Object-Oriented Analysis
and Design with Applications, by Grady Booch).
An object is
some private data and a set of operations that can access that
data. An object is requested to perform one of its operations by sending it a
message telling the object what to do. The receiver responds to the message by
first choosing the operation that implements the message name, executing this
operation, and then returning control to the caller.
(From Object-Oriented
Programming: An Evolutionary Approach, by Brad J. Cox).
Object Behaviour
how an object acts and
reacts in terms of its state changes and message passing;
the outwardly visible
and testable activity of an object;
Object Identity
the nature of an object
that distinguishes it from all other objects;
Note: two objects of the same
class and with the same state are still different objects
ฎ equality of objects issue:
'same
object' vs. 'equal object';
What is a class?
a class is a set
of objects that share a common structure and a common behaviour;
(From Object-Oriented
Analysis and Design with Applications, by Grady Booch).
Question: Is it possible to have two
classes with identical behaviour, but different
structure?
a class is an
abstract description of a set of objects; the implementation of a type;
(From Instant UML, by
Pierre-Alan Muller).
an object is an
instance of a particular class;
Abstraction
the essential
characteristics of an object that distinguishes it from all other kinds of
objects and this provide crisply-defined conceptual boundaries relative to the
perspective of the viewer;
the process of focusing
upon the essential characteristics of an object;
abstraction is one of
the fundamental elements of the object model;
Information Hiding
the process of hiding
all the secrets of an object that do not contribute to its essential characteristics;
typically the structure
of an object is hidden, as well as the implementation of its methods;
Encapsulation
the process of
compartmentalising the elements of an abstraction that constitute its structure
and behavior;
encapsulation serves
to separate the contractual interface of an abstraction and its
implementation;
encapsulation means:
" I don't care how you do it, just what you do.";
Inheritance
a relationship among
classes, wherein one class shares the structure and behaviour defined in one (single
inheritance) or more (multiple inheritance) other classes;
specialisation is to create sub-classes;
generalisation is to factor our common parts of classes
into a common super-class;
Use of object models
This
definition of an object is very general.
It
can be used
to
model an existing or proposed system
the
basis of object oriented analysis;
to
represent a way of constructing a piece of software
the
basis of object oriented design;
to
implement a piece of software
the
basis of object oriented programming.
We
do not really separate analysis and design
Notes on object behaviour
Note
that for these purposes the state of an object is interesting only in the way
that it affects the result of applying the operations of that object
Note
also that the object is defined on the assumption that some of its operations
can depend on operations to be supplied by other objects
This
is the notion of delegation and allows us to treat objects as
interacting components
Implementation issues
When
we come to implementation of the system, the description above is fleshed out
with concrete decisions about how the internal state of each type of object
will be maintained.
Typically
this involves defining
instance
variables
and the implementation of both
the
externally visible (public) operations used in the design
any
new internally restricted (private) operations.
Types, Classes and Instances
Before
we can use a in a design we must define a type of object and how it
appears externally.
Before
it can be used in a program we must also define as a class how this is
implemented internally.
An
instance is one particular object which exists during the execution of a
program.
Each
instance is constructed from a class definition.
Sometimes
there is only one instance of a class, sometimes there are many.
Transience, permanence and persistence
Some
instances remain in existence throughout the execution of the program - permanence
Some
appear and disappear - transience
The
potential always exists, however:
to
generate an arbitrary number of instances of a class;
to
construct and destroy instances as desired during execution.
If
an object remains in existence between runs of a program it is said to be persistent
Creating objects
Construction
of an object involves obtaining space in the memory of the computer for it,
reserving that space and naming it.
This
is typically done by
having a pointer or reference
variable of the desired class
invoking an operation which
asks a heap
manager or storage manager to set aside space for the required object
sets the
pointer variable to the address of this location
Constructors
At
the point of creation the user may wish to define certain initial actions for
the object, such as setting up starting values.
It
is useful if this sequence can be invoked automatically.
Most
languages have some means for defining this initialisation sequence
a constructor in C++
the body of the class in Simula
Memory management
Destruction
of an object involves returning the space it occupies to the heap manager for
re-use.
This
is either done:
explicitly through a destroy or
delete operation;
implicitly by allowing a scavenging
program to be invoked when the heap space is full or when the program is idle
waiting for some request to be processed (on the fly).
Such
a program is called a garbage collector.
It
looks for objects which are no longer referenced by any variable or linked list
in the program and reclaims them.
Object oriented graphics
We
take as our problem the design of a flexible package for graphics applications.
In
particular we are aiming at a drawing package.
We
want to allow the definition of pictures by means of a small, but extensible,
set of primitives.
We
note that most pictures can be decomposed into sub-pictures and eventually
into such primitives as lines, arcs, circles and texts.
We
start by thinking about the objects that inhabit our world of graphics.
Graphics objects
Clearly
the picture primitives can be objects.
We
can think of their required properties:
To remember their position, size
and shape.
To be drawn according to the above
on a screen.
To be able to be created and
deleted and for the picture to change correspondingly. This should leave other
objects correctly represented.
To be moved and scaled without
destroying other parts of the picture.
To be grouped and handled as a
group.
The display
The
canvas for displaying these objects is important.
It
has:
An
extent (possibly as a Cartesian space?)
A
memory of the current objects in the picture and the ability to display them.
Mapping objects onto the canvas
To
establish the correspondence between the graphics objects and the canvas, we
need to allow them to share the notion of a point.
All
objects are then defined by one or more points and a shape definition.
Thus
we may want to use
a
point object
Class Canvas
If
we consider the canvas, we note that it has certain
internal
state information.
This
should be protected appropriately.
This
will include:
The
dimensions of the display area.
These must
be in units shared with the graphics objects.
Background
colour etc.
The
list of objects currently in the picture.
Operations on the Canvas
The
operations on this internal data might include:
adding
an object;
deleting
an object;
initialising
an empty screen;
displaying
the object list;
returning
values of the internal state variables, such as extent, background colour etc.
resetting
some of the internal state variables, such as background colour etc.
Class Graphics_Object 1
We
could define separate objects for each type of basic
object.
This
has two
immediate
drawbacks.
Firstly
it prohibits easy building of mixed lists.
Second
it probably wastes effort in duplicating functions.
We
look for a suitable super-class.
(Sometimes
this sort of commonality is discovered later on and has to be reverse
engineered.)
Class Graphics_Object 2
Our
basic requirements are:
a
definition of position, depending on the shape of the object for its
significance;
an
ability to be part of a group (list) of objects;
a
knowledge of how to draw itself;
creation
and deletion;
Sub-classes of Graphics_Object
We
start with the primitives line, arc, circle and text.
This
is fairly arbitrary, but we can usually find primitives in a graphics package
for these.
Each
has to implement the drawing of its shape, which is required by its parent
class definition.
Each
has to have appropriate information about position (derived from the parent),
size and shape.
Groups of Graphics_Objects
This
is an important decision.
If
we wish to handle more complex shapes we must either add them as direct
sub-classes of Graphics_Object or find a way of representing grouped objects.
The
latter offers considerable benefits and we exploit the ability of objects to
be composed of components to make this possible.
Thus
we define one additional sub-class of Graphics_Object,
Compound_Object.
Compound_Object
This
has the following properties:
it
holds a list of other objects;
it
can invoke the drawing of the objects in its list as the implementation of its
own drawing operation;
it
draws its objects relative to its own position;
it
deletes its components when it is deleted.
Looking for re-use
At
this stage we have defined the basics of our classes.
It
is always sensible to look for more abstract mechanisms which we will need and
to either import these from an existing package or to write a package which is
independent of our particular application to supply them.
Re-use doesn't just happen It has to be worked for.
Candidate for reuse
The mechanism that we might spot
here is that of list manipulation.
We will need to insert, delete and
access items in groups.
Thus we choose to add an extra
layer to our design to support a re-usable list handling package.
This will add to the cost of
implementing this application, but will be a saving in all future applications
which require similar functions.
Thus, we should only make such an
investment if we think the mechanism is sufficiently general.
class Graphics
class Point - maps objects onto canvas. Has a List object for the current picture or maybe a compound
picture
class Canvas - the display.
class Graphics_Object
extends List_Item - has position and a
place marker for Draw.
class Line extends
Graphics_Object - has other end of the
line and appropriate implementation of Draw
class Arc extends
Graphics_Object - has size, shape and
appropriate implementation of Draw.
class Graphics
class Circle extends
Graphics_Object - has diameter and
appropriate implementation of Draw.
class Text extends
Graphics_Object - has contents and
appropriate implementation of Draw.
class Compound_Object extends
Graphics_Object - has a List and appropriate implementation of Draw, which calls the draw function in each of its members.
Some books
Software Design by David Budgen, Addison-Wesley 1993, ISBN
0-201-54403-2
Object Oriented Analysis and
Design with Applications, 2nd
Edition by Grady Booch, Benjamin-Cummings, ISBN 0-8053-5340-2
Object-Oriented Software
Construction by Bertrand Meyer,
Prentice-Hall, ISBN 0-13-629049-3
More books
Object Oriented Modelling and
Design by Rumbaugh, Blaha,
Premerlani, Eddy and Lorenson, Prentice-Hall, 0-13-630054-5
Object Oriented Methods, 2nd
Edition by Ian Graham, Addison-Wesley, ISBN 0-201-59371-8
Gamma,
Helm, Johnson and Vlissides, , Design Patterns, Elements of Reusable
Object-Oriented Software, Addison Wesley, 1995