# ps3.txt # Dan R. K. Ports # 6.170 PS3, 2004/02/24 # $Id: ps3.txt,v 1.4 2004/02/27 01:20:35 dan Exp $ REQUIREMENTS The spec does not clearly define what should happen when a Car is driving along a Route that contains a RoadSegment of zero length. The fraction of segment travelled no longer has a meaningful definition. In this implementation, the fraction is zero until drive() is called, then changed to 1. Hence, it is necessary to call drive() to arrive at the end of the segment (though this takes zero time) before calling makeTurn(). This behavior could certainly be changed, but the most reasonable thing to do would probably be to forbid segments whose start and end GeoPoints are equal. DESIGN 1. Route is implemented using an ArrayList to store the segments. An alternate implementation might use the front-and-back double-ended queue representation presented in lecture to store segments. This alternate implementation would be more efficient in situations where Routes were modified frequently (using many calls to addSegment and popSegment), but is considerably more complicated to implement. 2. If the precondition were changed, the new requires clause would be weaker and the new specification stronger than before. The implementation would have to be modified to deal with RoadSegments that are not properly oriented. Probably the simplest way to do this would be to modify addSegment to check whether the new segment is properly oriented, reverse it if it is not, and proceed normally. Nothing else would need to be changed. 3. Two Routes consisting of the same RoadSegments in the same order should be considered equal (in the context of equals()), because this is what the specification indicates. Since Routes are immutable, they are behaviorally equivalent in this case. 4. These Cars should not be judged equal, because they are not behaviorally equivalent: if we setSpeed() or drive() one of the cars, its speed and position will change, and they will no longer be observationally equivalent. (Cars are mutable.) TESTING This implementation was tested using the provided GeoPointTest and RoadSegmentTest, as well as RouteTest and CarTest, and passed all tests. Routes were tested by generating some Route objects using a small collection of RoadSegments. Since all tests required a few simple Route objects to manipulate, all tests depended on the constructor and addSegment(); The observers were tested, then the mutators, since the observers were necsesary to verify the results of the mutator. Cars were tested by generating a few instances, using the same Route objects from the Route test as their routes. Again, the observers were tested, then the simple mutators (setSpeed(), etc), followed by the more complex drive() and makeTurn() functions. The test case for Car depended on Route being implemented correctly, as well as RoadSegment and GeoPoint. ANALYSIS The GeoPoint, RoadSegment, Route, and Car classes were successfully implemented and tested. There are a few obvious possible improvements: - most preconditions are not checked. Though not required, it would probably be a good idea to do so. - hashCode() functions are not (meaningfully) implemented. - a Route could keep track of the total length of its segments; this would reduce the getLength() method from O(n) to O(1) time - Route could be implemented using an immutable-queue data structure for speed.