Title: Engr 691 Special Topics in Engineering Science Software Architecture Spring Semester 2004 Lecture Notes
1Engr 691Special Topics in Engineering Science
Software ArchitectureSpring Semester
2004Lecture Notes
2Data Abstraction
Created 19 August 2004
3Abstraction
- Maxim
- Simplicity is good complexity is bad.
- Abstraction
- Concentrating on the essentials and ignoring the
details - Sometimes described as "remembering the what and
ignoring the how". - Most effective weapon in fight against complexity
1
4Abstraction
2
5Two Kinds of Abstraction
- Procedural abstraction
- Separate logical properties of an action from
details of how the action is implemented - Use when developing an algorithm following the
top-down approach - Use when coding task in programming language,
make each task a procedure - Data abstraction
- Separate logical properties of data from details
of how data are represented - Focus on problems data rather than tasks
3
6Concrete Data Structure
- Structure and values of custom data types defined
by programmer are known to other parts of the
program - In Pascal or C, all data structures are visible
- E.g., a collection of records about the employees
of a company - store records in a global Pascal or C array
- the array and all its elements are visible to
all parts of program - any statement in program can directly access and
modify elements of the array
4
7Abstract Data Structure
- A module consisting of data and operations
- Data are hidden within module and can only be
accessed by means of operations - Its name and interface are known but not
implementation - Operations are explicitly given values are
defined implicitly by means of operations - Support information hiding
- Related concept encapsulation
- data and the operations that manipulate the data
are combined in a module
5
8Abstract Data Structure (cont.)
- State
- Manipulated by the operations.
- A value, or collection of information, held by
abstract data structure - Examples
- E.g., stack
- operations push(), pop(), and empty() for
accessing and manipulating - disallow direct access to concrete data structure
that implements stack. - implementation might use an array, a linked list,
or some other concrete data structure - actual implementation is "hidden" from the user
of the stack
6
9Abstract Data Structure (cont.)
- E.g., a collection of records about the employees
of a company - constraints
- only allow collection of records to be accessed
through a small group of procedures - array of records can be manipulated directly
inside group - other parts of program must use one of the
procedures in group to manipulate records in
collection - originally implemented with an array hidden
behind the interface - modifications of program, such as
- change the implementation from an array to a
linked list - move the collection to a disk file
- By approaching the design of the collection as an
abstract data structure, - limited the parts of the program changed to the
small group of procedures that used the array
directly - other parts of the program are not affected.
7
10Type and Concrete Data Type
- Type
- Category of entities sharing common
characteristics - Variable of type specified as
- a value (state) drawn from some set (domain) of
possible values - a set of operations that can be applied to those
values - Concrete data type
- values are most prominent features
- values and their representations are explicitly
prescribed - operations on the values are implicit
8
11Abstract Data Type (ADT)
- Set of abstract data structures all with same
domain of possible states and set of operations - Operations are explicitly prescribed
- Values are defined implicitly in terms of the
operations - Instance of the ADT
- Particular abstract data structure from an ADT
- Language support
- C and Pascal not directly support ADTs
- C and Java have class construct to directly
define ADTs
9
12Defining ADTs
- To specify an ADT, need
- Name of the ADT
- Sets (or domains) upon which it is built
- Type being defined
- Auxiliary types (e.g., primitive data types and
other ADTs) used as parameters or return values
of the operations. - Signatures (syntax or structure) of the
operations. - name
- input sets (i.e., the types, number, and order of
the parameters) - output set (i.e., the type of the return value)
10
13Defining ADTs
- Semantics (or meaning) of the operations
- Two primary approaches for specifying
- Axiomatic (or algebraic) approach
- set of logical rules (properties or axioms) that
relate the operations to one another - meanings of the operations are defined
implicitly in terms of each other - more elegant but difficult to apply
- Constructive (or abstract model) approach
- meaning of the operations explicitly in terms of
operations on other abstract data types - underlying model may be any well-defined
mathematical model or a previously defined ADT - more useful
11
14Defining ADTsAxiomatic Specification of
Unbounded Stack ADT
- Name
- Stack (of Item)
- Item represents the arbitrary unspecified type
for the entities stored in the stack A formal
generic parameter - Sets
- Stack
- set of all stack instances
- Item
- set of all items that can appear in a stack
instance - boolean
- primitive Boolean type False, True
12
15Defining ADTsAxiomatic Specification of
Unbounded Stack ADT
- Signatures
- Constructor
- constructs and initializes an instance of the
ADT - create Stack
- Mutator
- returns the instance with its state changed
- push (Stack, Item) Stack
- pop Stack Stack
- Accessor
- returns information from the state of an
instance without changing the state - top Stack Item
- empty Stack boolean
- Destructor
- destroys an instance of the ADT
- destroy Stack
13
16Defining ADTsAxiomatic Specification of
Unbounded Stack ADT
- Semantics
- Axioms for Stack ADT
- s instance of type Stack x entity of type
Item - top(push(s,x)) x
- precondition not empty(S)
- pop(push(s,x)) s
- precondition not empty(S)
- empty(create()) True
empty(create()) - empty(push(s,x)) False not
empty(push(s,x))
rewrite
rewrite
14
17Defining ADTsConstructive Specification of
Bounded Stack ADT
- Name
- StackB (of Item)
- Sets
- StackB
- set of all stack instances
- Item
- set of all items that can appear in a stack
instance - boolean
- primitive Boolean type
- int
- primitive integer type ..., -2, -1, 0, 1, 2,
...
15
18Defining ADTsConstructive Specification of
Bounded Stack ADT
- Signatures
- Constructor
- create int StackB
- Mutator
- push (StackB, Item) StackB
- pop StackB StackB
- Accessor
- top StackB Item
- empty StackB boolean
- full StackB boolean
- Destructor
- destroy StackB
16
19Defining ADTsConstructive Specification of
Bounded Stack ADT
- Semantics
- Precondition
- logical assertion that specifies required
characteristics of the values of arguments - Postcondition
- logical assertion that specifies characteristics
of the result computed by the operation with
respect to the values of the arguments. - Invariant
- Interface invariants
- states publically accessible features and
abstract properties of the ADT instance - Implementation (representation) invariants
- gives the required relationships among the
internal data fields of the implementation -
17
20Defining ADTsConstructive Specification of
Bounded Stack ADT
- Semantics of bounded Stack ADT
- create (int size) StackB S
- precondition
- size gt 0
- postcondition
- S' is a valid new instance of StackB
- S' has the capacity to store size items
- empty(S)
18
21Defining ADTsConstructive Specification of
Bounded Stack ADT
- Semantics of bounded Stack ADT
- push(StackB S, Item I) StackB
- precondition
- S is a valid StackB instance not full (S)
- postcondition
- S' is a valid StackB instance S' S with I
added as the new top - pop(StackB S) StackB S'
- precondition
- S is a valid StackB instance not empty(S)
- postcondition
- S' is a valid StackB instance S' S with the
top item deleted
19
22Defining ADTsConstructive Specification of
Bounded Stack ADT
- top(StackB S) Item I
- precondition
- S is a valid StackB instance not empty(S)
- postcondition
- I the top item on S
- empty(StackB S) boolean e
- precondition
- S is a valid StackB instance
- postcondition
- e is true iff S contains no elements (i.e., is
empty)
20
23Defining ADTsConstructive Specification of
Bounded Stack ADT
- full(StackB S) boolean f
- precondition
- S is a valid StackB instance
- postcondition
- f is true iff S contains no space for additional
items (i.e., is full) - destroy(StackB S)
- precondition
- S is a valid StackB instance
- postcondition
- StackB S no longer exists
21
24Java Classes Class and Instance Methods
- Class method
- Associated with class as a whole, not with any
specific instance - Has Keyword static
- public static void main(String args)
- // beginning code for the program
- Instance method
- Associated with an instance of the class
- No keyword static
- public void pop()
- // code for pop operation
22
25Java Classes Class and Instance Variables
- Class variable
- Associated with class as a whole only one copy
of the variable for entire class - With keyword static
- Instance variable
- Associated with an instance of the class each
instance has its own instance of the variable - With no keyword static
23
26Java Classes Public and Private Accessibility
- public components are accessible from anywhere in
the program - Associated with the class as a whole there is
only one copy of the variable for the entire
class - With keyword static
- Instance variable
- Associated with an instance of the class each
instance has its own instance of the variable - With no keyword static
24
27Java Classes Primitive or Reference Variables
- A Java variable is a strongly typed container in
memory that is declared to hold either - A value of the associated primitive data type
such as integers (int), floating point numbers
(double), booleans (boolean), and single
characters (char) - A reference to (i.e., memory address of) an
instance of the associated class (or other
reference) type
25
28Implementing ADTs as Java Classes
- 1.Use Java class construct to represent entire
ADT - To allow access to class from anywhere in
program, make the class public - Example
- public class StackB
- // implementation of instance methods
- //and data here
-
26
29Implementing ADTs as Java Classes
- 2. Use instance of Java class to represent
instance of ADT - Use variables of the class type to hold
references to instances - Example
- StackB stk
-
27
30Implementing ADTs as Java Classes
- 3. As each component of class defined, ensure
that semantics of ADT operations are implemented
appropriately - Appropriate implementation (representation)
invariant to capture what it means for internal
state of instance to be valid - Interface and implementation invariants
established (i.e., made true) by constructors and
preserved (i.e., kept true) by mutator and
accessor methods - Method's postcondition is established by method
in any circumstance when called with precondition
true - Class and its methods should be documented with
invariants, preconditions, and postconditions
28
31Implementing ADTs as Java Classes
- 4. Represent ADT's constructors by Java
constructor methods - Often include a parameterless default
constructor - Constructor is
- Method with same name as class
- No return type specified
- Normally invoked by Java operator new
- Example
- public class StackB
- public StackB(int size)
- // initialization code
- // rest of StackB methods and data ...
-
- StackB stk new StackB(100)
29
32Implementing ADTs as Java Classes
- 5. Represent ADT operations by instance methods
of class - State of ADT instance becomes implicit argument
of all method calls - Apply method to class instance by using selector
(i.e., "dot") notation - Example
- push an item x onto stk
- if (!stk.full())
- stk.push(x)
- examine top item and remove it
- if (!stk.empty())
- it stk.top()
- stk.pop()
-
30
33Implementing ADTs as Java Classes
- 6. Make the constructors, mutators, accessors,
and destructors public methods of the class
31
34Implementing ADTs as Java Classes
- 7. Represent ADT mutator operations by Java
procedure (i.e., void) methods, except those that
explicitly require new instances to be generated
(e.g., a copy or clone operation) - Example
- public void pop()
- // code to implement operation
32
35Implementing ADTs as Java Classes
- 8. For certain mutator operations (e.g., copy or
clone), implement Java methods to return new
instances rather than modify the current instance
33
36Implementing ADTs as Java Classes
- 9. Represent ADT accessor operations by Java
function methods of proper return type - Example
- public boolean empty()
- // code to implement operation
34
37Implementing ADTs as Java Classes
- 10. If necessary for deallocation of internal
resources, represent the ADT destructor methods
by explicit Java procedures - Normally just use automatic garbage collection
- Example
- public void destroy()
- // code to free resources
- Java framework allows finalize() method to be
called implicitly whenever garbage collector runs
35
38Implementing ADTs as Java Classes
- 11. Use private data fields to represent
encapsulated state of instance needed - Example
- public class StackB
- // public operations of class instance
- // encapsulated data fields of class instance
- private int topItem
- // Pointer to next index for insertion
- private int capacity
- // Maximum number of items in stack
- private Object stk // the stack
-
36
39Implementing ADTs as Java Classes
- 12. Do not use public data fields in the class
- public data fields violate the principle of
information hiding - Introduce appropriate accessor and mutator
methods to allow manipulation of the hidden state - 13. Include, as appropriate, private methods to
aid in implementation
37
40Implementing ADTs as Java Classes
- 14. Add any other methods needed to make the ADT
fit into the Java environment - Add public toString method
- returns a Java String reflecting the "value" of
instance in a format suitable for printing - Add public clone method
- creates new instance that has same value as
current instance
38
41Implementing ADTs as Java Classes
- 15. In general, avoid use of class (i.e., static)
variables - Good programming practice to use class constants
where appropriate - data fields declared with both static and final
modifiers - values may be initialized but cannot be changed
- Constants may be declared private if usage
restricted to class or public if users of class
also need access - Example
- public static final int SUNDAY 1
39
42Java Implementation of the Bounded Stack
- // A Bounded Stack ADT
- public class StackB
- // Interface Invariant Once created and until
destroyed, this - // stack instance has a valid and consistent
internal state - public StackB(int size)
- // Pre size gt 0
- // Post initialized new instance with
capacity size empty() - stk new Objectsize
- capacity size
- topItem 0
-
40
43Java Implementation of the Bounded Stack
- public void push(Object item)
- // Pre not full()
- // Post item added as the new top of this
instance's stack - stktopItem item
- topItem
- public void pop()
- // Pre not empty()
- // Post item at top of stack removed from
this instance - topItem--
- stktopItem null
-
41
44Java Implementation of the Bounded Stack
- public Object top()
- // Pre not empty()
- // Post return item at top of this
instance's stack - return stktopItem-1
- public boolean empty()
- // Pre true
- // Post return true iff this instance's
stack has no elements - return (topItem lt 0)
42
45Java Implementation of the Bounded Stack
- public boolean full()
- // Pre true
- // Post return true iff this instance's
stack is at full capacity - return (topItem gt capacity)
- public void destroy()
- // Pre true
- // Post internal resources released stack
effectively deleted - stk null
- capacity 0
- topItem 0
-
43
46Java Implementation of the Bounded Stack
- // Implementation Invariants 0 lt topItem lt
capacity - // stack is in array section
stk0..topItem-1 - // with the top at stktopItem-1, etc.
- private int topItem
- // Pointer to next index for insertion
- private int capacity
- // Maximum number of items in stack
private - Object stk // the stack
-
44
47Better Approach to Implementing ADTs in Java
- ?. Define Java interface that specifies type
signatures for ADT's mutator and accessor (and,
if needed, destructor) operations
45
48Better Approach to Implementing ADTs in Java
- II. Specify and document interface by interface
invariants, preconditions, and postconditions
that must be supported by any implementation - Example
- public interface StackADT
- // Interface Invariant Once created and
until destroyed, this - // stack instance has a valid and consistent
internal state - public void push(Object item)
- // Pre not full()
- // Post item added as the new top of this
instance's stack ... - public Object top()
- // Pre not empty()
- // Post return item at top of this
instance's stack - ...
-
46
49Better Approach to Implementing ADTs in Java
- III. Provide one or more concrete classes that
implement the interface - Example
- public class StackInArray implements
StackADT - // Interface Invariant Once created
and until destroyed, this - // stack instance has a valid and
consistent internal state - public StackInArray(int size)
- // Pre size gt 0
- // Post initialized new instance
with capacity size empty() -
- stk new Objectsize
- capacity size topItem
0 -
-
47
50Better Approach to Implementing ADTs in Java
- public void push(Object item)
- // Pre not full()
- // Post item added as the new top of this
instance's stack - stktopItem item
- topItem
- ...
- public Object top()
- // Pre not empty()
- // Post return item at top of this
instance's stack - return stktopItem-1
- ...
- // Implementation Invariants 0 lt topItem lt
capacity - // stack is in array section stk0..topItem-1
with the top at stktopItem-1 - private int topItem // Pointer to next index
for insertion - private int capacity // Maximum number of
items in stack - private Object stk // the stack
-
48
51Better Approach to Implementing ADTs in Java
- IV. Declare variables of ADT's interface type to
hold instances of any concrete class that
implements interface - Example
- StackADT theStack new StackInArray(100)
- theStack.push("Hello World")
49
52A Date (Day) ADT
- Constructor
- create(int y, int m, int d) Day D
- Precondition
- y ! 0 1 lt m lt 12 1 lt d
- lt days in month m
- (y,m,d) does not fall in the gap formed
by the change to the modern (Gregorian) calendar - Postcondition
- D' is a valid new instance of Day with year y,
month m, and day d
50
53A Date (Day) ADT
- Mutators
- setDay(Day D, int y, int m, int d) Day D'
- Precondition
- D is a valid instance of Day y ! 0
1 lt m lt 12 1 lt d lt days in month
(y,m,d) does not fall in the gap formed by the
change to the modern (Gregorian) calendar - Postcondition
- D' is a valid instance of Day D' D except
with year y, month m, and day d - ?? Should we include setDay, setMonth, and
setYear operations? What problems might arise?
51
54A Date (Day) ADT
- advance(Day D, int n) Day D'
- Precondition
- D is a valid instance of Day
- Postcondition
- D' is a valid instance of Day
- D' D with the date moved n days later (Negative
n - moves to an earlier date.)
52
55A Date (Day) ADT
- Accessors
- getDay(Day D) int d
- Precondition
- D is a valid instance of Day
- Postcondition
- d is day of the month from D, where 1 lt
d lt days - in month getMonth(D) (D is unchanged.)
- getMonth(Day D) int m
- Precondition
- D is a valid instance of Day
- Postcondition
- m is the month from D, where 1lt mlt12
- (D is unchanged)
53
56A Date (Day) ADT
- getYear(Day D) int y
- Precondition
- D is a valid instance of Day
- Postcondition
- y is the year from D, where y ! 0 (D is
unchanged) - getWeekday(Day D) int wd
- Precondition
- D is a valid instance of Day
- Postcondition
- wd is the day of the week upon which D
falls - 0 Sunday, 1 Monday, ..., 6 Saturday
53
57A Date (Day) ADT
- equals(Day D, Day D1) boolean eq
- Precondition
- D and D' are valid instances of Day
- Postcondition
- eq is true if and only if D and D' denote the
same calendar date (D and D' are unchanged) - daysBetween(Day D, Day D1) -gt int d
- Precondition
- D and D' are valid instances of Day
- Postcondition
- d is the number of calendar days from D1 to D,
i.e., equals(D,advance(D1,d)) would be true (D is
unchanged.)
55
58A Date (Day) ADT
- toString(Day D) -gt String s
- Precondition
- D is a valid instance of Day
- Postcondition
- s is the date D expressed in the format
"DaygetYear(D),getMonth(D),getDay(D)". - (D is unchanged.)
- Note
- This method is a "standard" method that should be
defined for most Java classes so that they fit
well into the Java language framework.
56
59A Date (Day) ADT
- Destructor
- destroy(Day D)
- Precondition
- D is a valid instance of Day
- Postcondition
- D no longer exists
57
60Java Class Implementation for Day
- import java.util.
- import java.io.
- public class Day
-
- //Interface Invariant Once created and until
destroyed, this - // instance contains a valid date.
getYear() ! 0 - // 1 lt getMonth() lt 12 1 lt getDay()
lt days in getMonth(). - // Also calendar date getMonth()/getDay()/ge
tYear() does not - // fall in the gap formed by the change to
the modern - // (Gregorian) calendar.
- // Constants for days of the week
- public static final int SUNDAY 1
- public static final int MONDAY 2
- public static final int TUESDAY 3
- public static final int WEDNESDAY 4
- public static final int THURSDAY 5
- public static final int FRIDAY 6
- public static final int SATURDAY 7
58
61Java Class Implementation for Day
- // Constructors
- public Day()
- // Pre true
- // Post the new instance's day, month, and
year set to today's - // date (i.e., the date of creation of the
instance) - // Implementation uses GregorianCalendar class
from the Java API to get today's date. -
- GregorianCalendar todaysDate new
GregorianCalendar() - year todaysDate.get(Calendar.YEAR)
- month todaysDate.get(Calendar.MONTH) 1
- day todaysDate.get(Calendar.DAY_OF_MONTH)
-
59
62Java Class Implementation for Day
- public Day(int y, int m, int d ) throws
IllegalArgumentException - // Pre y ! 0 1 lt m lt 12 1 lt d lt
days in month m - // (y,m,d) does not fall in the gap
formed by - // the change to the modern (Gregorian)
calendar. - // Post the new instance's day, month, and
year set to y, m, and d, respectively - // Exception IllegalArgumentException if y m d
not a valid date -
- year y
- month m
- day d
- if (!isValid())
- throw new IllegalArgumentException()
-
60
63Java Class Implementation for Day
- // Mutators
- public void setDay(int y, int m, int d) throws
IllegalArgumentException - // Pre y ! 0 1 lt m lt 12 1 lt d lt
days in month m - // (y,m,d) does not fall in the gap formed by
the - // change to the modern (Gregorian) calendar.
- // Post this instance's day, month, and year
set to y, m, and d, respectively - // Exception IllegalArgumentException if y m
d not a valid date - year y
- month m
- day d
- if (!isValid())
- throw new IllegalArgumentException()
-
- public void advance(int n)
- // Pre true
- // Post this instance's date moved n days
later. (Negative n - // moves to an earlier date.)
- fromJulian(toJulian() n)
61
64Java Class Implementation for Day
- // Accessors
- public int getDay()
- // Pre true
- // Post returns the day from this instance,
where 1 lt getDay() lt days - // in this instance's month
- return day
- public int getMonth()
- // Pre true
- // Post returns the month from this instance's
date, where 1 lt getMonth() lt 12 - return month
- public int getYear()
- // Pre true
- // Post returns the year from this instance's
date, where getYear() ! 0 - return year
62
65Java Class Implementation for Day
- public int getWeekday()
- // Pre true
- // Post returns the day of the week upon which
this instance falls, where - // 1 lt getWeekday() lt 7 1 Sunday,
2 Monday, ..., 7 Saturday - // calculate day of week
- return (toJulian() 1) 7 1
- public boolean equals(Day dd)
- // Pre dd is a valid instance of Day
- // Post returns true if and only if this
instance and instance - // dd denote the same calendar date
- return (year dd.getYear() month
dd.getMonth() - day dd.getDay())
-
63
66Java Class Implementation for Day
- public int daysBetween(Day dd)
- // Pre dd is a valid instance of Day
- // Post returns the number of calendar days
from the dd - // instance's date to this instance's date,
where - // equals(dd.advance(n)) would hold
- // implementation code
- return toJulian() - dd.toJulian()
-
- public String toString()
- // Pre true
- // Post returns this instance's date expressed
in the format "Dayyear,month,day" - return "Day" year "," month "," day
"" - // Destructors -- None needed
64
67Java Class Implementation for Day
- // Private Methods
- private boolean isValid()
- // Pre true
- // Post returns true iff this is a valid date
- Day t new Day()
- t.fromJulian(this.toJulian())
- return t.day day t.month month
t.year year
65
68Java Class Implementation for Day
- private int toJulian()
- // Pre true
- // Post returns Julian day number that begins
at noon of this day - // A positive year signifies A.D., negative year
B.C. - // Remember that the year after 1 B.C. was 1
A.D. (i.e., no year 0). Julian day 0 is a Monday.
- // A convenient reference point is that May 23,
1968, at noon is Julian day 2440000. - // Algorithm from Press et al., Numerical
Recipes in C, 2nd ed., Cambridge Univ. Press
1992. - int jy year
- if (year lt 0)
- jy
- int jm month
- if (month gt 2)
- jm
- else jy-- jm 13
- int jul (int) (java.lang.Math.floor(365.25
jy) java.lang.Math.floor(30.6001jm) day
1720995.0) - int IGREG 15 31(10121582) //
Gregorian Calendar adopted Oct. 15, 1582 - if (day 31 (month 12 year) gt IGREG)
// change over to Gregorian calendar - int ja (int)(0.01 jy)
- jul 2 - ja (int)(0.25 ja)
66
69Java Class Implementation for Day
- private void fromJulian(int j)
- // Pre true
- // Post this calendar Day is set to Julian date
j - // Algorithm from Press et al., Numerical
Recipes in C, 2nd ed., Cambridge Univ. Press 1992
- int ja j
- int JGREG 2299161 // the Julian date of
the adoption of the Gregorian calendar - if (j gt JGREG) // correct for
crossover to Gregorian Calendar - int jalpha (int)(((float)(j - 1867216) -
0.25) / 36524.25) - ja 1 jalpha - (int)(0.25 jalpha)
-
- int jb ja 1524
- int jc (int)(6680.0 ((float)(jb-2439870) -
122.1) /365.25) - int jd (int)(365 jc (0.25 jc))
- int je (int)((jb - jd)/30.6001)
- day jb - jd - (int)(30.6001 je)
- month je - 1
- if (month gt 12)
- month - 12
- year jc - 4715
67
70Java Class Implementation for Day
- // Implementation Invariants
- // year ! 0 1 lt month lt 12 1 lt day lt
days in month - // (year,month,day) not in gap formed by the
change to the - // modern (Gregorian) calendar
- private int year
- private int month
- private int day
-
68
71Client-Supplier Relationship
- supplier
- Developers of the ADT providers of the services
- client
- Users of the ADT users of the services
69
72Client-Supplier Relationship Concerns
- The supplier's concerns include
- Efficient and reliable algorithms and data
structures - Convenient implementation
- Easy maintenance
- The clients' concerns include
- Accomplishing their own tasks
- Using the supplier ADT without effort to
understand its internal details - Having a sufficient, but not overwhelming, set
of operations
70
73Client-Supplier Relationship Client-supplier
Contract
- Gives the responsibilities of the client
- Conditions under which the supplier must deliver
results - when the preconditions of the operations are
satisfied - Gives the responsibilities of the supplier
- Benefits the supplier must deliver make the
- postconditions hold at the end of the
operation - Protects the client by specifying how much must
be done by the supplier - Protects the supplier by specifying how little is
acceptable to the client
71
74Design Criteria for ADT (Class) Interfaces
- Cohesion
- All operations must logically fit together to
support a single, coherent purpose - ADT (class) should describe a single abstraction
- Simplicity
- Avoid needless features
- The smaller the interface the easier it is to use
the ADT (class) - No redundancy
- Avoid offering the same service in more than one
way - Eliminate redundant features
72
75Design Criteria for ADT (Class) Interfaces
- Atomicity
- Not combine several operations if they are needed
individually - Keep independent features separate
- All operations should be primitive
- Completeness
- All primitive operations that make sense for the
abstraction should be supported by the ADT
(class) - Consistency
- Provide a set of operations that are internally
consistent in - naming convention
- in use of prefixes like "set" or "get", in
capitalization - in use of verbs/nouns/adjectives)
- use of arguments and return values
- order and type of arguments
- behavior (i.e., make operations work similarly)
- Avoid surprises and misunderstandings
73
76Design Criteria for ADT (Class) Interfaces
- Reusability
- Do not customize ADTs (classes) to specific
clients - Make them general enough to be reusable in other
contexts - Robustness with respect to modifications
- Design the interface of an ADT (class) so that it
remains stable even if the implementation of the
ADT changes - Convenience
- Provide additional operations where appropriate
- Add convenience operations only for frequently
used combinations after careful study
74
77Acknowledgement
- This work was supported by a grant from Acxiom
Corporation titled The Acxiom Laboratory for
Software Architecture and Component Engineering
(ALSACE).
75