1 Abstraction
1 Abstraction
Topics:
Abstraction, modules and objects, system modeling, introduction to MATLAB
Abstraction
If you open an atlas you will often first see a map of the world. This map will show only the
most significant features. For example, it may show the various mountain ranges, the ocean
currents, and other extremely large structures. But small features will almost certainly be
omitted.
A subsequent map will cover a smaller geographical region, and will typically possess more
detail. For example, a map of a single continent (such as Africa) may now include political
boundaries, and perhaps the major cities.
A map over an even smaller region, such as a country, might include towns as well as cities,
and smaller geographical features, such as the names of individual mountains. A map of an
individual large city might include the most important roads leading into and out of the city.
Maps of smaller regions might even represent individual buildings.
Notice how, at each level, certain information has been included, and certain information has
been purposely omitted. There is simply no way to represent all the details when an artifact is
viewed at a higher level of abstraction. And even if all the detail could be described (using tiny
writing, for example) there is no way that people could assimilate or process such a large
amount of information.
1|Page
Consider the average person’s understanding of an automobile. A layman’s view of an
automobile engine, for example, is a device that takes fuel as input and produces a rotation of
the drive shaft as output. This rotation is too fast to connect to the wheels of the car directly,
so a transmission is a mechanism used to reduce a rotation of several thousand revolutions per
minute to a rotation of several revolutions per minute. This slower rotation can then be used to
propel the car. This is not exactly correct, but it is sufficiently close for everyday purposes. We
sometimes say that by means of abstraction we have constructed a model of the actual system.
In forming an abstraction, or model, we purposely avoid the need to understand many details,
concentrating instead of a few key features. We often describe this process with another term,
information hiding.
Information Hiding
Layers of Abstraction
In a typical program written in the object-oriented style there are many important levels of
abstraction. The higher level abstractions are part of what makes an object-oriented program
object-oriented.
■ At the highest level a program is viewed as a “community” of objects that must interact with
each other in order to achieve their common goal. This notion of community finds expression
in object-oriented development in two distinct forms:
● Firstly, there is the community of programmers, who must interact with each other in the real
world in order to produce their application.
● Secondly, there is the community of objects that they create, which must interact with each
other in a virtual universe in order to further their common goals.
2|Page
Key ideas such as information hiding and abstraction are applicable to both levels.
Each object in this community provides a service that is used by other members of the
organization. At this highest level of abstraction the important features to emphasize are the
lines of communication and cooperation, and the way in which the members must interact
with each other.
■ The next level of abstraction is not found in all object-oriented programs, nor is it supported
in all object-oriented languages. However, many languages permit a group of objects working
together to be combined into a unit (Module). Examples of this idea include packages in Java,
name spaces in C++, or units in Delphi. The unit allows certain names to be exposed to the
world outside the unit, while other features remain hidden inside the unit or Module.
■ The next two levels of abstraction deal with the interactions between two individual objects.
Often we speak of objects as proving a service to other objects. We build on this intuition by
describing communication as an interaction between a client and a server (meaning an object
that is providing a service).
The two layers of abstraction refer to the two views of this relationship; the view from the client
side and the view from the server side.
In a good object-oriented design we can describe and discuss the services that the server
provides without reference to any actions that the client may perform in using those services.
The billboard describes the services provided by a data structure, such as a Stack. Often this
level of abstraction is represented by an interface, a class-like mechanism that defines
behaviour without describing an implementation:
3|Page
Note:
In early stages of software development a critical problem is finding the right level of
abstraction. A common error is to dwell on the lowest levels, worrying about the
implementation details of various key components, rather than striving to ensure that the high
level organizational structure promotes a clean separation of concerns.
The programmer (or, in larger projects, the design team) must walk a fine line in trying to
identify the right level of abstraction at any one point of time. One does not want to ignore or
throw away too much detail about a problem, but also one must not keep so much detail that
important issues become obscured.
■ The next level of abstraction looks at the same boundary but from the server side. This level
considers a concrete implementation of the abstract behaviour.
For example, there are any number of data structures that can be used to satisfy the
requirements of a Stack. Concerns at this level deal with the way in which the services are
being realized.
4|Page
■ The last level of abstraction considers a single task in isolation; that is, a single method.
Concerns at this level of abstraction deal with the precise sequence of operations used to
perform just this one activity. For example, we might investigate the technique used to perform
the removal of the most recent element placed into a stack.
Each level of abstraction is important at some point during software development. In fact,
programmers are often called upon to quickly move back and forth between different levels of
abstraction.
5|Page
Other Forms of Abstractions
Abstraction is used to help understand a complex system. In a certain sense, abstraction is the
imposition of structure on a system. The structure we impose may reflect some real aspects of
the system (a car really does have both an engine and a transmission) or it may simply be a
mental abstraction we employ to aid in our understanding.
This idea of abstraction can be further subdivided into a variety of different forms (See Figure
Above). A common technique is to divide a layer into constituent parts. This is the approach
we used when we described an automobile as being composed of the engine, the transmission,
the body and the wheels. The next level of understanding is then achieved by examining each
of these parts in turn.
This is nothing more than the application of the old maxim divide and conquer. Other times we
use different types of abstraction. Another form is the idea of layers of specialization (See
Figure Below).
The ideas of division into parts and division into specializations represent the two most
important forms of abstraction used in object-oriented programming. These are commonly
known as is-a and has-a abstraction.
6|Page
The idea of division into parts is has-a abstraction. The meaning of this term is easy to
understand; a car “has-a” engine, and it “has-a" transmission, and so on.
The concept of specialization is referred to as “is-a" abstraction. The term comes from the
English sentences that can be used to illustrate the relationships.
Yet another form of abstraction is to provide multiple views of the same artifact. Each of the
views can emphasize certain detail and suppress others, and thus bring out different features of
the same object. A layman’s view of a car, for example, is very different from the view required
by a mechanic.
The most common technique people use to help understand complex systems is to combine
abstraction with a division into component parts. Our description of an automobile is an
example of this. The next level of understanding is then achieved by taking each of the parts,
and performing the same sort of analysis at a finer level of detail. A slightly more precise
description of an engine, for example, views it as a collection of cylinders, each of which
converts an explosion of fuel into a vertical motion, and a crankshaft, which converts the up
and down motion of the cylinder into a rotation.
Another example might be organizing information about motion in a human body. At one level
we are simply concerned with mechanics, and we consider the body as composed of bone (for
rigidity), muscles (for movement), eyes and ears (for sensing), the nervous system (for
transferring information) and skin (to bind it all together). At the next level of detail we might
ask how the muscles work, and consider issues such as cell structure and chemical actions. But
chemical actions are governed by their molecular structure. And to understand molecules we
break them into their individual atoms.
Any explanation must be phrased at the right level of abstraction; trying to explain how a person
can walk, for example, by understanding the atomic level details is almost certainly difficult,
if not impossible.
7|Page
Encapsulation and Interchangeability
A key step in the creation of large systems is the division into components. Suppose instead of
writing software, we are part of a team working to create a new automobile. By separating the
automobile into the parts engine and transmission, it is possible to assign people to work on
the two aspects more or less independently of each other. We use the term encapsulation to
mean that there is a strict division between the inner and the outer view; those members of the
team working on the engine need only an abstract (outside, as it were) view of the transmission,
while those actually working on the transmission need the more detailed inside view.
For these ideas to be applicable to software systems, we need a way to discuss the task that a
software component performs, and separate this from the way in which the component fulfils
this responsibility.
Note!
Catalogs
When the number of components in a system becomes large it is often useful to organize the
items by means of a catalog. We use many different forms of catalog in everyday life. Examples
include a telephone directory, a dictionary, or an internet search engine. Similarly, there are a
variety of different catalogs used in software.
One example is a simple list of classes. Another catalog might be the list of methods defined
by a class. A reference book that describes the classes found in the Java standard library is a
very useful form of catalog. In each of these cases the idea is to provide the user a mechanism
to quickly locate a single part (be it class, object, or method) from a larger collection of items.
In software we use the terms interface and implementation to describe the distinction between
the what aspects of a task, and the how features; between the outside view, and the inside view.
8|Page
An interface describes what a system is designed to do. This is the view that users of the
abstraction must understand.
The interface says nothing about how the assigned task is being performed. So to work, an
interface is matched with an implementation that completes the abstraction. The designers of
an engine will deal with the interface to the transmission, while the designers of the
transmission must complete an implementation of this interface.
Similarly, a key step along the path to developing complex computer systems will be the
division of a task into component parts. These parts can then be developed by different
members of a team. Each component will have two faces, the interface that it shows to the
outside world, and an implementation that it uses to fulfil the requirements of the interface.
The division between interface and implementation not only makes it easier to understand a
design at a high level (since the description of an interface is much simpler than the description
of any specific implementation), but also make possible the interchangeability of software
components (as I can use any implementation that satisfies the specifications given by the
interface).
The idea that an interface describes the service provided by a software component without
describing the techniques used to implement the service is at the heart of a much more general
approach to managing the understanding of complex software systems. This sort of abstraction
can be viewed from the point of view of a whole community of people becoming involved in
the process of sending flowers as illustrated in the figure below.
9|Page
Each member of the community is providing a service that is used by other members of the
group. No member could solve the problem on their own, and it is only by working together
that the desired outcome is achieved.
Composition
Composition is another powerful technique used to create complex structures out of simple
parts. The idea is to begin with a few primitive forms, and add rules for combining forms to
create new forms. The key insight in composition is to permit the combination mechanism to
be used both on the new forms as well as the original primitive forms.
A good illustration of this technique is the concept of regular expressions. Regular expressions
are a simple technique for describing sets of values, and have been extensively studied by
theoretical computer scientists. The description of a regular expression begins by identifying a
basic alphabet, for example the letters a, b, c and d. Any single example of the alphabet is a
regular expression. We next add a rule that says the composition of two regular expressions is
a regular expression. By applying this rule repeatedly we see that any finite string of letters is
a regular expression:
Abaccaba
The next combining rule says that the alternation (represented by the vertical bar |) of two
regular expressions is a regular expression. Normally we give this rule a lower precedence that
composition, so that the following pattern represents the set of three letter values that begin
with ab, and and end with either an a, c or d:
Parenthesis can be used for grouping, so that the previous set can also be described as follows:
ab(a|c|d)
Finally the * symbol (technically known as the kleene-star) is used to represent the concept
“zero or more repetitions". By combining these rules we can describe quite complex sets. For
example, the following describes the set of values that begin with a run of a's and b's followed
by a single c, or a two character sequence dd, followed by the letter a.
(((a|b)*c)|dd)a
10 | P a g e
This idea of composition is also basic to type systems. We begin with the primitive types, such
as int and boolean. The idea of a class then permits the user to create new types. These new
types can include data fields constructed out of previous types, either primitive or user-defined.
Since classes can build on previously defined classes, very complex structure can be
constructed piece by piece.
Yet another application of the principle of composition is the way that many user interface
libraries facilitate the layout of windows. A window is composed from a few simple data types,
such as buttons, sliders, and drawing panels.
Various different types of layout managers create simple structures. For example, a grid layout
defines a rectangular grid of equal sized components, a border layout manger permits the
specification of up to five components in the north, south, east, west, and center of a screen.
As with regular expressions, the key is that windows can be structured as part of other windows.
Imagine, for example, that we want to define a window that has three sliders on the left, a
drawing panel in the middle, a bank of sixteen buttons organized four by four on the right, and
11 | P a g e
a text output box running along the top. We can do this by laying simple windows inside of
more complex windows (Figure Above).
Many computer programs can themselves be considered a product of composition, where the
method or procedure call is the mechanism of composition. We begin with the primitive
statements in the language (assignments and the like).
With these we can develop a library of useful functions. Using these functions as new
primitives, we can then develop more complex functions. We continue, each layer being built
on top of earlier layers, until eventually we have the desired application.
Layers of Specialization
Yet another approach to dealing with complexity is to structure abstraction using layers of
specialization. This is sometimes referred to as a taxonomy. For example, in biology we divide
living things into animals and plants. Living things are then divided into vertebrates and
invertebrates. Vertebrates eventually includes mammals, which can be divided into (among
other categories) cats and dogs, and so on.
The key difference between this and the earlier abstraction is that the more specialized layers
of abstraction (for example, a cat) is indeed a representative of the more general layer of
abstraction (for example, an animal). This was not true when, in an earlier example, we
descended from the characterization of a muscle to the description of different chemical
interactions. These two different types of relations are sometimes described using the heuristic
keywords “is-a" and has-a". The first relationship, that of parts to a whole, is a has-a relation,
as in the sentence “a car has an engine". In contrast, the specialization relation is described
using is-a, as in “a cat is a mammal".
The principle of abstraction permits us to suppress some details so that we can more easily
characterize a fewer number of features. We can say that mammals are animals that have hair
and nurse their young, for example. By associating this fact at a high level of abstraction, we
can then apply the information to all more specialized categories, such as cats and dogs.
The same technique is used in object-oriented languages. New interfaces can be formed from
existing interfaces. A class can be formed using inheritance from an existing class. In doing
so, all the properties (data fields and behaviour) we associate with the original class become
available to the new class.
12 | P a g e
Figure: The AWT class hierarchy
Let’s examine the Java AWT (Abstract Windowing Toolkit) library. When a programmer
creates a new application using the AWT they declare their main class as a subclass of Frame,
which in turn is linked to many other classes in the AWT library (Figure Above). A Frame is
an special type of application window, but it is also a more specialized type of the general class
Window. A Window can hold other graphical objects, and is hence a type of Container. Each
level of the hierarchy provides methods used by those below. Even the simplest application
will likely use the following:
Patterns
When faced with a new problem, most people will first look to previous problems they have
solved that seem to have characteristics in common with the new task. These previous problems
can be used as a model, and the new problem attacked in a similar fashion, making changes as
necessary to fit the different circumstances.
This insight lies behind the idea of a software pattern. A pattern is nothing more than an attempt
to document a proven solution to a problem so that future problems can be more easily handled
13 | P a g e
in a similar fashion. In the object-oriented world this idea has been used largely to describe
patterns of interaction between the various members of an object community.
A simple example will illustrate this idea of a pattern. Imagine one is developing an application
that will operate over a network. That means that part of the application will run on one
computer, and part will run on another computer linked by a network connection. Creating the
actual connection between the two computers, and transmitting information along this
connection, are details that are perhaps not relevant to large portions of the application. One
way to structure these relationships is to use a type of pattern termed a proxy. The proxy is an
intermediary that hides the network connection. Objects can interact with the proxy, and not
be aware that any type of network connection is involved at all. When the proxy receives a
request for data or action, it bundles the request as a package, transmits the package over the
network, receives the response, unpackages the response and hands it back to the client. In this
fashion the client is completely unaware of the details of the network protocol.
Notice how the description of the pattern has captured certain salient points of the interaction
(the need to hide the communication protocol from the client) while omitting many other
aspects of the interaction (for example, the particular information being communicated
between client and server).
Summary
People deal with complex artefacts and situations every day. Thus, while you might not yet
have created complex computer programs, you will have experience in using the tools that
computer scientists employ in managing complexity.
● The most basic tool is abstraction, the purposeful suppression of detail in order to emphasize
a few basic features.
● Abstraction is often combined with a division into components. For example, we divided the
automobile into the engine and the transmission. Components are carefully chosen so that they
14 | P a g e
encapsulate certain key features, and interact with other components through a simple and fixed
interface.
● The division into components means we can divide a large task into smaller problems that
can then be worked on more-or-less independently of each other. It is the responsibility of a
developer of a component to provide an implementation that satisfies the requirements of the
interface.
● A point of view that turns out to be very useful in developing complex software system is
the concept of a service provider. A software component is providing a service to other
components with which it interacts. In real life we often characterize members of the
communities in which we operate by the services they provide. (A delivery person is charged
with transporting flowers from a florist to a recipient). Thus this metaphor allows one to think
about a large software system in the same way that we think about situations in our everyday
lives.
● A particular tool that has become popular in recent years is the pattern. A pattern is simply a
generalized description of a solution to a problem that has been observed to occur in many
places and in many forms. The pattern described how the problem can be addressed, and the
reasons both for adopting the solution and for considering other alternatives.
Practice Questions
1. What is abstraction?
15 | P a g e
3. What is information hiding?
6. What do the terms client and server mean when applied to simple object-oriented programs?
9. What are the basic features of composition as a technique for creating complex systems out
of simple parts?
10. How does a division based on layers of specialization differ from a division based on
separation into parts?
16 | P a g e