Java Reference
In-Depth Information
This time, we assume that we have an instance variable transporterRoom of class Room ,
where we store the reference to our transporter room. 6 Now the check is independent of the
room's name. That is a bit better.
There is still a case for further improvement, though. We can understand the shortcomings of
this solution when we think about another maintenance change. Imagine that we want to add
two more transporter rooms so that our game has three different transporter locations.
A very nice aspect of our existing design was that we could set up the floor plan in a single spot,
and the rest of the game was completely independent of it. We could easily change the layout of the
rooms, and everything would still work—high score for maintainability! With our current solution,
though, this is broken. If we add two new transporter rooms, we have to add two more instance var-
iables or an array (to store references to those rooms), and we have to modify our goRoom method
to add a check for those rooms. In terms of easy changeability, we have gone backwards.
The question, therefore, is: Can we find a solution that does not require a change to the com-
mand implementation each time we add a new transporter room? Following is our next idea.
We can add a method isTransporterRoom in the Room class. This way, the Game object
does not need to remember all the transporter rooms—the rooms themselves do. When rooms
are created, they could receive a boolean flag indicating whether a given room is a transporter
room. The goRoom method could then use the following code segment:
if(currentRoom.isTransporterRoom()) {
nextRoom = getRandomRoom();
}
else {
nextRoom = currentRoom.getExit(direction);
}
Now we can add as many transporter rooms as we like; there is no need for any more changes
to the Game class. However, the Room class has an extra field whose value is really needed only
because of the nature of one or two of the instances. Special-case code such as this is a typical
indicator of a weakness in class design. This approach also does not scale well should we decide
to introduce further sorts of special rooms, each requiring its own flag field and accessor method. 7
With inheritance, we can do better and implement a solution that is even more flexible than
this one. We can implement a class TransporterRoom as a subclass of class Room . In this
new class, we override the getExit method and change its implementation so that it returns a
random room:
public class TransporterRoom extends Room
{
/**
* Return a random room, independent of the direction
* parameter.
* @param direction Ignored.
* @return A random room.
*/
6 Make sure that you understand why a test for reference equality is the most appropriate here.
7 We might also think of using instanceof, but the point here is that none of these ideas is the best.
Search WWH ::




Custom Search