Lab 3: Genericity and Inheritance
NEW SIMPLER VERSION OF THE TEST IN THE ARCHIVE, PLEASE RE-DOWNLOAD
UPDATED CLASS SCHEMAS WITH MORE HELP
Generic Methods for Filtering & String Handling
Start with the correction of the previous lab:
tp3-start-en.zip (add the lib directory with the mockito jar).
A new package "common" appears. It contains a Utils class with generic methods to :
- represent functions as objects (a predicate, a function2 that applies b to a and returns the result)
- filter out from a iterable structure by a predicate (filter)
- reduce, which applies a function (2 params) from left to right in a list (see its application in mkstring)
- mkstring that concatenates elements with a given separator (using "reduce")
Work to do:
- Implement the missing code inside the filter function
- Use "filter" to modify the getProperties method in "AbstractCreature" so that static fields are not taken into account. You can use a new Predicate with the following apply code:
public boolean apply(Field input) {
return !Modifier.isStatic(input.getModifiers());
}
- replace the "mkString" method in toString of "AbstractCreature" by the Utils version. This should work flawlessly while being generic!
- refactor the code of creatureAround() so to use a filter function
Inheritance and refactoring
In the first lab, you were asked final questions about the code structure of the first version of the simulator, questions like:
- What to do with some of the utility functions?
- What to do with the fact that logic of the Environment and the visualization are kept together?
Use the refactoring support in Eclipse (right-click and get into submenus on elements you want to refactor) to get the following inheritance hierarchy for creatures:
Then do another refactoring to abstract and separate the simulation from its visualisation. You should be close to the following organization (proceed step by step and with eclipse refactoring as much as possible) :
NEW Hints:
- Refactor first methods that use x,y so to use Point2D (you cannot make it automatically), check that tests continuously run OK
- Create needed getters and setters
- Extract interfaces by the refactoring tools of Eclipse (progressively go towards the proposed class schemas, continue to check that tests run OK)
- Do not use Eclipse refactoring to move big methods such as "creatureAround()" (which moves from Environment to SmartCreature. Do not run the tests until the refactoring is done, you need to carefully refactor the tests as well
- Use the following code for the Simulator thread (and note that all methods of the Simular class must be declared synchronized):
thread = new Thread() {
@Override
public void run() {
while (true) {
synchronized (this) {
while (!running) {
try {
wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
try {
synchronized (this) {
Thread.sleep(executionDelay);
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
simulate();
}
}
};
At home
If you want to complete this lab at home, think about testing the generic string methods of the first exercise:
- What kind of things would you test? generic parameters ? specific forms of strings ?
- Then build a test suite that covers all relevant aspects
--
PhilippeCollet - 24 Oct 2013
to top