Abstract Data Types: Understanding Modular Construction and Information Hiding, Study notes of Construction

An overview of abstract data types (ADTs), their purpose, and the different ways to implement and hide their concrete representation. ADTs allow for modular construction of software systems by providing a clear operational behavior while hiding implementation details. first-order and second-order information hiding, and includes examples in an imaginary programming language and Java.

Typology: Study notes

2021/2022

Uploaded on 10/10/2022

yngve99
yngve99 🇸🇪

5

(2)

65 documents

1 / 5

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
ABSTRACT DATA
TYPE
The purpose of abstract data types is to allow the
modular construction of software systems through the
composition of components whose individual behavior
is well understood.
An
abstract data type
(ADT) is a programmer-defined
data type, comprising a specification and at least one
implementation. The specification gives an abstract
description of the behavior of instances of the type,
independently of any particular implementation. The
provider of an abstract type implementation is obliged
to ensure that it obeys the specification perfectly.
So
long
as
this is the case, users of the type need only
understand the specification, rather than the imple-
mentation, to know how values of the type will behave.
This approach to software construction has a number
of advantages. The specification may be given in a
language other than the programming language used
to implement it, and in particular an axiomatic specifi-
cation language such
as
Z
or
VDL
(see
VIENNA
DEFINI-
TION
LANGUAGE)
may be used. This allows the user of
an abstract data type to gain a very clear understanding
of its operational behavior without having to under-
stand the lower-level details of its implementation.
Different implementations can be substituted, for
example for performance reasons, without affecting
the user code. Finally, the user code can be written
before any implementation exists, allowing parallel
construction in a large system.
The implementation itself consists of a concrete rep-
resentation, a set of operations that may be performed
on that representation, and an interface to those oper-
ations. The interface must, of course, correspond to
that given
as
part of the specification. It is a critical
requirement for an abstract data type that the interface
operations provide the only access by which the con-
crete representation is manipulated. In this case,
whether
or
not the interface provides a correct imple-
mentation of the abstract specification depends only on
the coding of the interface operations, independently
of
any pattern of use.
Some programming languages provide explicit
sup-
port for abstract data types; some provide implicit
support, and some provide no support at all. However,
the concept of abstract typing may be usefully thought
of
as
a programming discipline rather than a syntactic
construct, and it is possible to program in this disci-
pline in many languages that do not possess explicit
syntactic support,
as
well as in those which do.
Most languages that explicitly support pure models of
abstract data types have evolved in the research do-
main, and include, for example, Alphard,
CLU,
Euclid,
ML
(arguably a commercial language), Napier88, and
Quest. Commercial languages with at least some sup-
port for the key concepts include Ada
(q.v.),
C++
(q.v.),
Java
(q.v.),
and some dialects of Pascal
(4.v.).
pf3
pf4
pf5

Partial preview of the text

Download Abstract Data Types: Understanding Modular Construction and Information Hiding and more Study notes Construction in PDF only on Docsity!

ABSTRACT DATA TYPE

The purpose of abstract data typesis to allow the modular construction of software systems through the composition of components whose individual behavior is well understood.

An abstract data type (ADT) is a programmer-defined data type, comprising a specification and at least one implementation. Thespecificationgives an abstract description of the behavior of instances of the type, independently of any particular implementation. The provider of an abstract type implementation is obliged to ensure that it obeys the specification perfectly. So long as this is the case, users of the typeneedonly understandthe specification, rather than the imple- mentation, to know how valuesof the type will behave.

This approach to software construction has a number of advantages. Thespecificationmaybegivenin a language other than the programming language used to implement it, and in particular an axiomatic specifi-

cation language such as Z or VDL (see VIENNADEFINI-

TION LANGUAGE) may be used. This allows the user of an abstract data type to gain a very clearunderstanding of its operational behavior without having to under- stand the lower-leveldetails of its implementation. Different implementationscanbe substituted, for

examplefor performance reasons, without affecting the user code. Finally, the user code can be written beforeany implementation exists, allowingparallel construction in a large system. The implementation itself consists of a concrete rep- resentation, a set of operations that may be performed on thatrepresentation, and an interface to those oper- ations. The interface must, of course, correspond to

that given as part of the specification. It is a critical

requirement for an abstract data type that theinterface operations provide the only access by which the con- crete representation is manipulated. In this case, whether or not the interface provides a correct imple- mentation of the abstract specification depends only on the coding of the interface operations, independently of any pattern of use. Someprogramming languagesprovideexplicit sup- port for abstract data types; some provideimplicit support, and someprovide no support at all. However, the conceptof abstract typing may be usefullythought of as a programming discipline rather than a syntactic construct, and it is possible to program in this disci- pline in many languages that do not possess explicit

syntactic support, as well as in those which do.

Most languages that explicitly support pure models of abstract data types have evolved in the research do- main, and include, for example, Alphard, CLU, Euclid,

ML (arguably a commercial language), Napier88, and

Quest. Commercial languages with at least some sup- port for the key concepts include Ada (q.v.), C++ (q.v.), Java (q.v.), and some dialects of Pascal ( 4. v. ).

2 ABSTRACTDATA TYPE

AnExample ADT

As a motivating example, consider an abstract defini- tion of a simple counter, the kind a shepherd might use for counting sheep. We will give one in English for want of a better specification language. The abstract interface consists of the operations “click,” “look,”and “reset.” “Click” and “reset” have no argument or result; the former has the effect of incrementing the counter, while the latter zeros it. “Look” also has no argument, but returns a natural number, representing the current value of the counter.

Notice that thespecification is completely independent of the programming language used for coding. How- ever, although the definition might be completely abstract, it is still necessary to find sufficient common- ality between the specification and coding languages for the interface operations to be defined inboth. In this case we can manage with a programming language that provides procedures and integers; here is an obvious implementation in an imaginary language:

l e t c o u n t e r R e p : = 0 p r o c e d u r e c l i c k 0 ; c o u n t e r R e p :=

p r o c e d u r e r e s e t 0 ; c o u n t e r R e p : = 0 p r o c e d u r e l o o k 0 - > i n t e g e r ;

c o u n t e r R e p + 1

r e t u r n ( c o u n t e r R e p )

However, this implementation of the abstract descrip- tion does not make an abstract type, as the operational interface can be compromised by a change to the vari- able c o u n t erRep from another context, without using c 1 ic k or r e s e t. Neither is it completely correct, since we should really note in the specification that it should be used only for flocksup to the maximum integer size! Although this may seem pedantic, such detail is impor- tant in the construction of large systems.

First- and Second-Order Information Hiding There are two ways in which the concrete representa- tion of an abstract data type can be protected from un- lawful manipulation: by making it incapable of being denoted in the language, or by giving it a type that pre- cludes illegal operations. Mechanisms in these classes are known respectively as first-order and second-order information hiding. The critical difference is that second-order mechanisms allow instances of the abstract type itself to appear in the operational signa- ture (the specification of the types of the operations in terms of the types of their operands and return values). The use of first-order information hiding is thus restricted to state transformation models, where the abstract instance is hidden behind interface operations that affect and report aspects of its state (see PROGRAM-

MING LANGUAGE SEMANTICS).Second-order hiding is more flexible, as it allows abstract values to bepassed around along with operations that may be applied to them.

In the example, instances of the counter itself do not appear in the interface, and therefore first-order infor- mation hidingmay be used. Wegive the example coded in an imaginary block-structured language with higher-order (first-class)procedures (see BLOCKSTRUC- TURE; and FUNCTIONALPROGRAMMING).Higher-order procedure types can be used to give the type of the interface (“counter”) without relying upon specific abstract type syntax, and block structure can be used to prevent the concrete representation from being accessed other than by the interface procedures. After the initializing block has been executed, the variable c o u n t e r Rep is out of scope with respect to the rest of the program. The implementation of the higher-order procedure mechanism must of course preserve the location for as long as the procedures are accessible.

t y p ec o u n t e r i s s t r u c t u r e ( c l i c k , r e s e t : p r o c e d u r e ( ) , l o o k : p r o c e d u r e ( )

-> i n t e g e r )

l e t m y c o u n t e r = { l e t c o u n t e r R e p : = 0 s t r u c t u r e ( c l i c k = p r o c e d u r e O ;

r e s e t = p r o c e d u r e O ;

l o o k = p r o c e d u r e O -> i n t e g e r ;

)

c o u n t e r R e p : = c o u n t e r R e p + l ,

c o u n t e r R e p := 0 ,

r e t u r n ( c o u n t e r R e p )

}

Thiskind of procedural encapsulation follows essen- tially the same model as that of many object-oriented languages, and differs onlyby the syntactic mechanism by which the instance variables (corresponding to the concrete representation) are kept inaccessible from other partsof the code. It is reasonable to regard some instances of classes, in some object-oriented languages, as abstract data types. However, other object-oriented languages have models of typing and dynamic method binding ( 4. v. ) that make it impossibleto define abstract types, as no guarantee can be given that the concrete representation is accessedonly by the originally defined interface procedures.

To introduce a second-order example we will model the same kind of counter, but slightly change the abstract definition to model a collection of counters. Each has the same interface operations, modeled now as procedures thatoperateoncounters, and two new interface functions are introduced: one to create

4 ABSTRACT DATA TYPE

Thismodelmakes the abstract algebra a structural type, the abstract type name a bound variable of the algebra, andthe operators fields of the algebra in- stance. This approach avoids introducing anysignifi- cant names with the creation of an insthce. Further- more, it decouples the definition of the algebra signa- ture from the creation of its instances, makingit possiblefor a number of different implementations to coexist. It is essential that a further syntactic mech- anismis introduced in order to avoid the mixing of operations between instances. One such mechanismis the o p e n clause, which introduces a new constant binding (myCPack) for the abstract package. Any con- struct that ensures a constant bindingmaybe used, although the o p e n clause also provides a convenient syntaxfor introducing an identifier to stand for the abstract type: o p e n r e p P a c k a s m y C P a c k [ c o u n t e r T y p e I i n { l e t n e w c o u n t e r = m y C P a c k. n e w C o u n t e r l e t c l i c k = m y C P a c k. c l i c k l e t m y c o u n t e r = n e w c o u n t e r ( ) / / v a l u e o f t y p e c o u n t e r T y p e c l i c k ( m y c o u n t e r ) }

OBJECT-ORIENTED INFORMATION HIDING

The final well-known mechanism that allows the ab- straction required for second-order information hiding

is the class mechanism of object-oriented languages.

Suchmechanisms control the scoping of instance variables and methods, and can be used to describe abstract data types. Once again note that theconverse is not the case, andmanyclassesdescribedin such languages cannot usefully beregarded as abstract types because they lack the necessary static properties. The following shows the examplecoded in Java: c l a s s c o u n t e r { p r i v a t e :

p u b l i c :

i n t c o u n t e r R e p ;

C o u n t e r 0 { c o u n t e r R e p = O ; } v o i d c l i c k 0 { c o u n t e r R e p + + ; } v o i d r e s e t 0 { c o u n t e r R e p = O ; } i n t l o o k 0 { r e t u r n c o u n t e r R e p ; } s t a t i c b o o 1 g r e a t e r( C o u n t e r x, C o u n t e r y )

{ r e t u r n ( x. c o u n t e r R e p > y. c o u n t e r R e p ) ; }

} : Object-oriented information hidingis an interesting mix between first- and second-order models. The con- cept of an object is essentiallya first-order model, andis normally used in the state transformation paradigm. However, the scoping rules for method definition can allow the coding of second-order models bygiving access to the internal state of more than oneobject of the sameclass, as in the above example. This isa com-

mon paradigm in the languages C++ and Java. While neither language provides a perfect degree of safety with respect to the criteria identilied earlier, both give a reasonable degree of confidence in the absence of malicious interference. For code using this class, onlythe class name C o u n t e r

and the namesof the public interface functions may be

accessed. Only the identifier C o u n t e r is required to be in global scope and unique within the composition of modules, makingless of a probleminsystem composition thanthe ML mechanism. The other operator namesare effectivelylabels brought into scope by the dereferencing of an instance of the class or, in the case of static functions, the class itself. c l a s s U s e c o u n t e r { p u b l i c : i n t u s e C o u n t e r 0 { C o u n t e r a , b ; a = n e w ( C o u n t e r ) ; b = n e w ( C o u n t e r ) ; a - > c l i c k ( ) ; r e t u r n ( C o u n t e r : : g r e a t e r ( a , b ) 1 ; } } Also deserving mention in the context of object- oriented programming and abstract data types, is the concept of “componentware” models of programming

(see COMPONENTSOFTWARE), as typified by CORBA

and DCOM. Such models again give practical, if not enforced, guarantees of the externally observable con- sistent behavior, and the componentwareparadigm is

arguably that of geographically distributed abstract

data types.

Conclusion To summarize the mainconcepts presented, it is most

helpful to view an abstract data type as a programming

discipline that helps with theconstruction of large soft- ware systems by providing components whose behav- ior may be understood at an abstract level. To achieve this, it must have a precise abstract specification, an interface and implementation that capture the specifi- cation, and a sufficient degree of protection from deliberate or accidental misuse.

Bibliography

  1. Liskov, B., Atkinson, R., Bloom, T., Moss, E., SchaiTert, J. C., Scheifler, R., and Synder, A. CLU Reference Manual. New York: Springer-Verlag.
  2. Milner,R., and Harper, R. The Definition of Standard ML. Cambridge, MA:MIT Press.
  3. Schmidt, D.A. The Structure of Typed Programming Languages. Cambridge, MA:MIT Press.

ACCESS METHODS 5

  1. Paulson, L. Standard ML for the Working Programmer,
  2. Meyer, B. Object-Oriented Software Construction, 1999. Henning, M. and Vinoski, S. Advanced CORBA

2nd Ed. Cambridge: Cambridge University Press. 2nd Ed. Upper Saddle River, NJ: Prentice Hall.

Programming with C++. Reading, MA: Addison-Wesley. Richard Connor

ACCESS METHODS

Introduction

An access method is a technique foraccessing data that has been placed on some kind of mass storage device; magnetic tape at one time, but now most often a hard disk (4.v.). While the term accessmethod is most properly used to describe the method used to retrieve the data, it is also frequently used as a syno- nym for the program or routine that implements the method. AU computer manufacturers provide service routines to implement access methods, generally as a component of an operating system (4.v.). Instead of access method, terms such as data management, file control program, and 11'0 (input or output)supervisor are sometimes used, depending on the manufacturer. Theterminologyused in this article is common to several manufacturers, including IBM ( 4. v. ) , but not all manufacturers support every variant described.

Evolution of Access Methods

In the earliest days of computers, each programmer had to program the flow of datato and from I/O devices, including auxiliarystorage units such as disks, drums, and tapes. This required that the programmer be familiarwith the characteristics of particular devices and write code for functions such as testing for avail-

able channels ( q. v. ) , testing for I/O errors, and pro- gramming error recovery. Manyof these functions were time dependent. Programming 1/0 in this man- ner tended to bind the programs to aparticular device. When the storage device changed, program code had to be substantially modified.

Since I/O programming tended to be fairlysimilar from one program to the next, it was not long before utilityservice programs (or access methods) were developed. Such programs perform, in a generalized

manner, all of the interactions with the storage device.

The programmer needmerely be concerned with requesting a record and providing a location in storage for it. The division of functions is depicted in Fig. 1. Note the assumption in this figure that the application program can continue processing while data is being transferred, a point to which we return below.

The interface between the application program and the access method tends to be fairly simple and standard- ized and is generally reducible to a set of parameters. The usual technique is to place the input and output parameters in a table. This table may be called(among other names) the DTF (DefineTheFile), DD (Data Definition), or FCT (File Control Table). The param- eters include a pointer (4. v. ) to an areaof storage to and from which the data transfer is to be made (Le. the record bufer-q.v.), the size of the record, whether electronic labels are to bewritten or read at the front of the file, and pointers to special error-handling routines. The application program need only placethe necessary data into the table. This is a far easier task than having to write a customized I/O routine. When invoked by the application, the access method uses the contents of the table to perform the task requested. When a new storage device becomes available, only the access meth- od, not the application program's main logic, need be modified. Such device independence, a form of trans- parency ( q. v. ) ,^ implies that, to^ the user of an appli- cation, changes in storage devices are invisible,Le. they need not be concerned with them.

Request data Parallel processing Check for record of application completion I II^ II II of datatransfer

processor

"" l m e t h o dAccess

I I I I I (^) I Initiate ~ data I transfer I

I I I I I I 7 I Error I checking, I post

I/O processor Figure 1. Division of functions.

I I completion Data of data transfer transfer