|
cs205: engineering software? |
(none) 20 September 2010 |
cs205 Data Abstraction Notes
(Friday 8 September - Monday 11 September)
What are the advantages and disadvantages of using abstract data types?
What are the minimal operations a (useful) data abstraction must provide?
Is it reasonable for a datatype to have no creators?
Is it reasonable for a datatype to have no observers?
public class SetWhat missing operations are needed for an adequate Set datatype?{ OVERVIEW: A Set is a mutable, unbounded set of objects of type T. A typical Set is {x_1, ..., x_n }. public Set() EFFECTS: Initializes this to an empty set: { }. public boolean add(T el) MODIFIES: this EFFECTS: Adds el to the elements of this: thispost = thispre U { el } Returns true iff el was not an element of thispre. public boolean contains(T el) EFFECTS: public void union(Set<T> t)
Is it necessary to provide union?
The Abstraction Function maps a concrete state to an abstract state:
AF: C → AIt is a function from concrete representation to the abstract notation introduced in overview specification.
// AF (c) = { AFT (c.els[i]) | 0 <= i < c.els.size () }
Representation Invariant
The Representation Invariant expresses properties all legitimate objects of the ADT must satisfy. It is a function from concrete representation to boolean:
I: C → boolean
To check correctness we assume all objects passed in to a procedure satisfy the invariant and prove all objects satisfy the invariant before leaving the implementation code.
public class Set<T> {
// OVERVIEW: A Set is a mutable, unbounded set of objects of type T.
// A typical Set is {x_1, ..., x_n }.
// Representation:
private Vector<T> rep;
// RepInvariant (c) = c.rep contains no duplicates && c.rep != null
// && all elements of c.rep are of non-null
If we instead used RepInvariant (c) = true which operations would be
easier to implement correctly? Which would be harder?
Where can an implementer of a datatype assume the rep invariant is true?
Where must an implementer of a datatype ensure the rep invariant is true?
public class Graph {
// OVERVIEW:
// A Graph is a mutable type that represents an undirected
// graph. It consists of nodes that are named by Strings,
// and edges that connect a pair of nodes.
// A typical Graph is: < Nodes, Edges >
// where
// Nodes = { n1, n2, , nm }
// and
// Edges = { {a_1, b_1}, ..., {a_n, b_n} }
// (note that the elements of Edges are unordered sets)
// Creator
public Graph ()
// EFFECTS: Initializes this to a graph
// with no nodes or edges: < {}, {} >.
// Mutators
public void addNode (String name) throws DuplicateException
// MODIFIES: this
// EFFECTS: If name is in Nodes, throws DuplicateException.
// Otherwise, adds a node named name to this:
// this_post = < Nodes_pre U { name }, Edges_pre >
public void addEdge (String fnode, String tnode) throws
NoNodeException, DuplicateException
// MODIFIES: this
// EFFECTS: If s and t are not names of nodes in
// this, throws NoNodeException. If there is already an edge
// between s and t, throws DuplicateEdgeException.
// Otherwise, adds an edge between s and t to this:
// thispost = < Nodespre, Edgespre U {fnode, tnode} >
// Observers
public boolean hasNode (String node)
// EFFECTS: Returns true iff node is a node in this.
Set getNeighbors (String node)
// REQUIRES: node is a node in this
// EFFECTS: Returns the set consisting of all nodes in this
// that are directly connected to node:
// { n | {node, n} is in this.edges }
}