SWE/CS 332 In Class Exercise #11
Names:
This is a recap exercise.
public class BoundedQueue {
private Object rep[];
private int front = 0;
private int back = -1;
private int size = 0;
private int count = 0;
public BoundedQueue(int size) {
if (size > 0) {
this.size = size;
rep = new Object[size];
back = size - 1;
} }
public boolean isEmpty() { return (count == 0); }
public boolean isFull() { return (count == size); }
public int getCount() { return count; }
public void put(Object e) {
if (e != null && !isFull()) {
back++;
if (back >= size)
back = 0;
rep[back] = e;
count++;
} }
public Object get() {
Object result = null;
if (!isEmpty()) {
result = rep[front];
rep[front] = null;
front++;
if (front >= size)
front = 0;
count--;
}
return result;
}
@Override public String toString() {
String result = "front = " + front;
result += "; back = " + back;
result += "; size = " + size;
result += "; count = " + count;
result += "; rep = [";
for (int i = 0; i < rep.length; i++) {
if (i < rep.length-1)
result = result + rep[i] + ", ";
else
result = result + rep[i];
}
return result + "]";
} }
- How would Liskov describe a typical bounded queue?
- What is wrong with
toString()
? What needs to be done to fix it?
Make it so.
- Write some sample client code to exercise the data structure.
Include some non-happy-path cases.
Would Bloch likely change the behavior? If so, how?
- Write contracts for each method (as written), including the constructor.
Are there any missing methods?
- Build a rep-invariant. Focus on the code in
get()
.
There are also lots of constraints on the array indices; these are quite tricky to get right.
The constructor also introduces some complexity.
- Suppose we removed the line
rep[front] = null;
from get()
.
-
Informally, why is this wrong?
-
Formally, where does the correctness proof break down?
-
Could a client ever see the problem?
-
Now that we've done some AF/RI analysis,
what changes make the implementation better?
btw - this is code straight out of a textbook.
-
Could this data structure be made immutable? If so, what would change
in the contracts and method headers? What would likely change in the implementation?