Specification

advertisement
EECE 310:
Software Engineering
Modular Decomposition, Abstraction
and Specifications
Decomposition
• Goal: Create small programs that interact
with one another in simple, well-defined
ways, to reduce complexity
• Criteria for good decomposition
1. Sub-problems at the same level of detail
2. Each can be solved independently
3. Can be combined to solve the original problem
2
Decomposition Example
Large Unsolved Problem
SP1
SP2
SP3
SP4
SP5
SP6
Combined
solution
3
What often happens in practice ?
Large Unsolved Problem
SP1
SP4
SP5
SP2
SP3
SP7
SP9
Combined
solution ?
4
Learning Objectives
• Define abstraction and types of abstraction
• Write specifications in the standard format
• Write precise specifications that are
sufficiently restrictive, but not too restrictive
• Differentiate between “good” and “bad”
specifications
• Develop implementations to satisfy a
specification
5
Abstraction
• A way to do decomposition productively
• Definitions:
– Application of many-to-one mapping
– Simplification of the problem that hides
irrelevant details, characteristics
– Grouping of related entities into distinct
categories without worrying about the details
6
Abstraction Kinds
1. By Parameterization
– Abstracts from the identity of the data
2. By Specification
– Abstracts from implementation details
to the behavior users can depend on
– Isolates modules from one another’s
implementations
– Provides a clear contract between the
user and the implementer of module
7
Abstraction by Parameterization
• Write the procedure once, but change its parameters
– Generalizes modules so they can be used many times
– Fundamental technique used in programming
• Example: Recipe for making pasta (Serves 2 people)
–
–
–
–
–
Step 1: Boil 2 cups of water in a sauce-pan
Step 2: Add 6 cups of pasta when water comes to a boil
Step 3: Sautee 5 grams of vegetables in an another pan
Step 4: Mix the sauteed vegetables with the cooked pasta
Step 5: Add pasta sauce, cheese and salt to taste
• But, what if we wanted to make pasta for 5 people ?
– Should we develop a new recipe from scratch ?
8
Abstraction by Specification
• Hide implementation details of a module and focus
instead on what it does (rather than how it does it)
– Specify the behavior that module’s users can depend on
– Can generalize across multiple implementations
– Change module’s behavior without changing its usage
• Example: Recipe for making pasta (Serves 2)
–
–
–
–
–
Step 1: Boil 2 cups of water in a sauce-pan
Step 2: Add 6 cups of pasta when water comes to a boil
Step 3: Sautee 5 grams of vegetables in an another pan
Step 4: Mix sauteed vegetables with the cooked pasta
Step 5: Add pasta sauce, cheese and salt to taste
9
Benefits of
Abstraction by Specification
1. Locality -- the implementation of an
abstraction can be read or written without
needing to examine the implementations of
any other abstractions.
2. Modifiability -- an abstraction can be reimplemented without requiring changes to
any abstractions that use it.
10
Learning Objectives
• Define abstraction and types of abstraction
• Write specifications in the standard format
• Write precise specifications that are
sufficiently restrictive, but not too restrictive
• Differentiate between “good” and “bad”
specifications
• Develop implementations to satisfy a
specification
11
Specification
• Tells the client of an abstraction what the
client is expected to do
• Tells the implementer of an abstraction what
implementation must do to satisfy the client
• Contract between client and implementer
– Client will rely only on behavior in specification
– Implementer only needs to provide this behavior
– Implementer is free to change implementation
12
Specifications: Formal Vs Informal
Formal Specs
Informal Specs
• Written in a mathematically
precise language
• Have only one meaning or a
finite set of meanings
• Can be understood by
humans and machines
• Automated tools can check
code against specifications
• Written in an informal
language (English)
• Have different meanings
depending on the reader
• Can be understood only by
humans (for the most part)
• Manual effort needed to
check code against specs
In this class, we will write informal
specifications, but you will write formal specs in
13
Recipes: Analogy
• A good specification is
like a recipe and has the
following components:
–
–
–
–
What is being done ?
What is required ?
How to do it ?
Are there things that one
needs to look for ?
– Any other things to note
• Recipes are written in a
standard format defined
by the Chefs association
14
How to write procedural specifications
?
• Choose a name for the procedure that is descriptive
• Procedural specifications should consist of:
– REQUIRES: What does the procedure need ?
– MODIFIES: What data does the procedure modify ?
– EFFECTS: What does the procedure produce at the end ?
• The code for the procedure is not part of its
specification, but must match the specification
15
Procedural Specifications - 1
• Factorial: Fact(n) = 1 * 2 *3 …. * n * (n- 1)
static int Fact(int n) {
// EFFECTS: Returns the factorial of n
//
where fact(n) = 1 * 2 * … * n
// REQUIRES: n >= 0
// MODIFIES: None (this can be dropped)
…
}
16
Procedural Specifications – 2
(Multiple Implementations)
Using Iteration
Using recursion
public static int fact(int N ) {
int result = 1;
public static int fact(int N) {
int result;
if (N==0)
result = 1;
else
result = N * fact(N – 1);
for (int i =1; i<=N; i++) {
result = result * i;
}
return result;
}
return result;
}
Both implementations have the same behavior.
(Is this always true ? Can you see any difference
17
Learning Objectives
• Define abstraction and types of abstraction
• Write specifications in the standard format
• Write precise specifications that are
sufficiently restrictive, but not too restrictive
• Differentiate between “good” and “bad”
specifications
• Develop implementations to satisfy a
specification
18
Sorting Routine: Informal Spec
• Take an array as argument, sort it in place
• What kind of arrays do we want to handle ?
– Arrays of ints (primitive type)
– Array should be non-null (or maybe not)
– No need to say that array elements are non-null
(implied by first clause)
REQUIRES clause
• Should only capture the requirements on array
that are not implied by the type signature
– Do not need to say anything about the types of the
arguments, unless they cannot be inferred
– Do not mention the return type of the procedure
public static void sort( int[] a ) {
// REQUIRES: Array a not be Null
}
MODIFIES Clause
• Modifies clause only specifies what objects
(on heap) are modified by the procedure
– Does not include return value of procedure
– Does not say anything about how it is modified
public static void sort( int[] a ) {
// REQUIRES: Array a not be Null
// MODIFIES: Array a
EFFECTS Clause
• Specifies what the EFFECT of the procedure is
– Include both return value and heap objects
– Include any exceptions thrown by the procedure
– Must say how the modifications are made
public static void sort( int[] a ) {
// REQUIRES: Array a not be Null
// MODIFIES: Array a
// EFFECTS: Rearranges the elements of a in
// ascending order (i.e., lowest to highest)
Group Activity
• Write a specification for the sort program that
sorts an array of String objects (in
alphabetical order)
public static void sort( String[] a ) {
// REQUIRES:
// MODIFIES:
// EFFECTS:
Solution: Group Activity
• The array may contain null objects
– Need to put this in the REQUIRES clause
public static void sort( String[] a ) {
// REQUIRES: a is not NULL &&
//
Elements of a are not NULL
// MODIFIES: Array a
// EFFECTS: Re-arranges the elements of array a
// in alphabetical order (i.e., lowest to highest)
// Uses String.compareTo for determining order
24
Learning Objectives
• Define abstraction and types of abstraction
• Write specifications in the standard format
• Write precise specifications that are
sufficiently restrictive, but not too restrictive
• Differentiate between “good” and “bad”
specifications
• Develop implementations to satisfy a
specification
25
Procedural Specifications: Example 1
public class Vectors {
//OVERVIEW: Provides useful standalone procedures
//
for manipulating vectors
public static void removeDuplicates ( Vector v ) {
// REQUIRES: No element of vector v is null
// MODIFIES: v
// EFFECTS: Removes all duplicate elements from v;
// uses equals method to determine duplicates.
// The order of the remaining elements may change
}
}
26
Procedural Specification: Example 2
• Does the following implementation satisfy the
specification ?
public static void removeDuplicates ( Vector v )
// REQUIRES: No element of vector v is null
// MODIFIES: v
// EFFECTS: Removes all duplicate elements from v;
// uses equals method to determine duplicates.
// The order of the remaining elements may change
v.clear();
}
27
Procedural Specifications: Example 4
public class Vectors {
//OVERVIEW: Provides useful standalone procedures
//
for manipulating vectors
}
public static void removeDuplicates ( Vector v ) {
// REQUIRES: No element of vector v is null
// MODIFIES: v
// EFFECTS: Removes all duplicate elements from v;
// uses the equals method to determine duplicates.
// The order of the remaining elements may change
// but the set of elements formed by the new vector is
// identical to the set of elements formed by the old one
}
28
What’s the problem ?
• The original specification was too weak
– Any implementation could satisfy it, even
incorrect ones
– The specification should be sufficiently restrictive
to allow only correct implementations
– If it is important to you, then write it down
• From the point of view of the client
• Make sure you can use the specification
Remember …
• Specifications are many-to-one mappings
– Many implementations may satisfy a specification
– But some may be wrong because the specification is
not restrictive enough !
• A specification is like a contract. If the
implementer can get away by doing less and yet
satisfy the specification, they may choose to !
– It is your responsibility to put it in the specification
30
Learning Objectives
• Define abstraction and types of abstraction
• Write specifications in the standard format
• Write precise specifications that are
sufficiently restrictive, but not too restrictive
• Differentiate between “good” and “bad”
specifications
• Develop implementations to satisfy a
specification
31
What makes a good specification ?
• Sufficiently restrictive
• Minimally constraining
• Clear – no room for ambiguity
These guidelines are necessarily vague, so let us
see some examples
32
Sufficiently Restrictive
public static int search (int[] a, int x)
// REQUIRES: a is not null
// EFFECTS: Examines each of a[0], a[1], ... , in order and
returns the index of the element that equals to x.
What’s wrong with the above specification ?
1. What if there is more than one element equal to x ?
2. What if there is no element equal to x ?
How will you fix these issues ?
33
Minimally Constraining
• Do you really care that the procedure examines
each element in turn ?
• Also, do you need the first element that equals x ?
• Precludes non-linear implementations such as binary search
public static int search (int[] a, int x)
// REQUIRES: a is not null
// EFFECTS: Examines each of a[0], a[1], ... , in some order and
//
//
returns the index of an element that equals to x.
If no such element is found, it returns - 1
34
Clarity
• The above specification is NOT clear. Do we return an
element whose index is x, or do we return the index
of an element that equals x. This is the problem with
natural language. So we need to be more clear.
public static int search (int[] a, int x)
// REQUIRES: a is not null
// EFFECTS: Examines each of a[0], a[1], ... , in some order and
//
//
//
returns the index of an element that equals to x.
i.e., returns an i, such that a[i] = x and 0 <=i <a.length
if no such element is found, it returns -1.
Note the use of i.e. to indicate redundancy
35
Learning Objectives
• Define abstraction and types of abstraction
• Write specifications in the standard format
• Write precise specifications that are
sufficiently restrictive, but not too restrictive
• Differentiate between “good” and “bad”
specifications
• Develop implementations to satisfy a
specification
36
Implementation
• Do NOT handle cases in the REQUIRES clause
– EFFECTS clause is satisfied only if REQUIRES holds
• Do NOT modify entities not in MODIFIES clause
• Do only what the EFFECTS clause says, no more
– Clients should rely upon specification, not
implementation
– If EFFECTS clause is underspecified, then it’s a
problem in the specification and needs to be fixed
37
Group Activity - 1
• Develop implementation for the specification
below (write legibly on a separate sheet)
public static int search (int[] a, int x)
// REQUIRES: a is not null
// EFFECTS: Examines each of a[0], a[1], ... , in any order
//
//
and returns the index of an array element that
equals to x. If no such element is found, returns -1.
38
Group Activity - 2
1.Write a procedure “count” that uses the
specification of “search” to count the
number of occurrences of a given
element in the array. Note that you may
not modify the original array in any way.
2.Take an implementation of search from
the class. Does your implementation of
count match with the search
implementation ?
39
To do before next class
• Read Chapters 1, 3 and 9 in the textbook
• Try exercises 3.1 to 3.4 and 3.7
• Attempt Assignment 1 on class webpage
– Learn Java NOW if you haven’t started yet !
– Prepare for quiz 1 on Java
40
Download