Software Construction: Data Abstraction Flashcards
To build a call graph
look at all the method calls in a method definition and draw a line on the graph from the method to each method it calls.
Hypothesis driven debugging
making careful educated guesses, with plans for how to validate or invalidate them.
If you notice a value (or field) is showing up as wrong, then
there are three typical problems to check: you’re not retrieving the value correctly, or you’re not setting the field correctly, or you’re not setting it at all.
If you are changing a parameter’s value inside a method, and aren’t seeing that value reflected once the method has returned
check to make sure you’re not just changing a local variable instead of the object referenced by the parameter.
If you’re looking for an object based on some field, and not finding that object,
make sure you are comparing against the field values, rather than accidentally comparing object references. (We will see an even more elegant way to do this in the second course)
An exception’s stack trace message
tells us where the execution died (in the method at the top, right below the message)
An index out of bounds exception means
you tried to access off the end of a collection. Remember to check whether you are in range (likely by using the collection.size() method) before accessing a collection.
A null pointer exception means
you tried to execute a method, or access a field in an object that has not been instantiated. Before using an object, it’s best to check if it exists! You can use if (theObject!=null) to check.
Remember to keep checking hypotheses even if you have found your bug.
There may be more than one thing wrong.
There are four phases in our design approach (often applied in a circular way):
specification of public interface, usage scenarios, test specification, and finally implementation.
Specification means
determining exactly what the public operations should be, and what they should expect/assume when called (REQUIRES), what they change (MODIFIES) and what they produce (EFFECTS).
Usage scenarios means
looking at all the ways that your abstraction will be used – this will perhaps motivate new operations, which will then need to be specified
Test specification means
writing a thorough and rigorous test suite for every operation prior to implementation
Implementation involves
deciding on an internal representation of the data in the abstraction, and then implementing the public and supporting private methods to make it work. The tests should all pass when the implementation is done
a REQUIRES specification of a method indicates
the preconditions of running that method.
typically we do not include trivial preconditions (such as the parameter must be non-null), but instead focus on
conditions of correct running of the method.
If a method can be called regardless of the state of the program, then
no REQUIRES clause is needed.
mutability means that we can
set the value of an object and it will remain changed. We saw this with variables earlier in this course.
The MODIFIES clause indicates
whether a method, or any method it calls, mutates any object.
If a method mutates its own object, we indicate that it MODIFIES:
this
If a method mutates another object, we indicate that it modifies
that other object.