A public forum for discussing the design of software, from the user interface to the code architecture. Now closed.
You have a world in which intelligent agents, acting according to certain goals, hunt each other on a Map, which itself is composed of Tiles. Tiles are independent of other Tiles; the Map is responsible for the organization and layout of Tiles in a collective way.
You want to be able to render the Map differently according to different parameters of interest. For instance, in one view you might want to simply show the landscape of each Tile graphically. In another, you might want to replace each tile with a text character (say, "~" for water, "*" for bushes, and so on) and render the result to a text file. In a third view you might want to render each Tile as a 2-dimensional square colored to represent the height of the Tile (say, blue Tiles are lower elevations, while red Tiles are higher elevations).
Clearly there are many different ways of showing the same Tile. Let's call each of these a RenderStrategy. Although it would be possible to embed the logic of how to render a Tile in the Map, and then to call different Map methods based on which view one wants to invoke, this seems sloppy and like it's not part of the Map responsibility. Instead, it seems like this should be abstracted in a completely different way.
How should these various RenderStrategies be abstracted so that, at runtime, you can switch between arbitrary RenderStrategies to show the Map in different ways? Is there an obvious design pattern that covers this problem?
void renderTile(TileInfo tileInfo);
void renderMap(IRenderStrategy renderStrategy)
foreach (TileInfo tileInfo in this.m_tileCollection)
Are Tiles represented as separate subclasses (WaterTile, MountainTile, PlainsTile, etc?) or is there just one Tile class with attributes?
If tiles are represented with subclasses, how often do you add new ones?
If the answers here are "yes" and "not often", the Visitor pattern would seem to be an excellent fit here. From the GOF book:
Represent an operation to be performed on the elements of an object structure. Visitor lets you define a new operation without changing the classes of the elements on which it operates.
Visitor is a little complicated to explain here, and there are coupling issues, but for what you're describing it seems pretty good. If you're not familiar with this pattern let me know and I'll type up some more detailed ideas.
I'm familiar with the Visitor pattern (I didn't want to mention it in my description lest I bias someone, though).
The attributes of the Tile determine the nature of the Tile itself. There is a small handful of inherited Tiles. However, more concerning is the fact that there can be an arbitrary number of different RenderStrategies, and that this list is likely to expand or change frequently.
Either strategies need to know about tiles, or tiles need to know about strategies (or a third type, for example the map, needs to know strategies and tiles in order to mediate between them).
If the number of tile-types is fixed and the number of strategy-types is expanding, then it's better for strategies to know about tiles.
Perhaps you're looking for http://www.google.ca/search?hl=en&q=strategy+pattern&meta=
Is this for school?
Monday, February 19, 2007
I'll second what Mr. Wells said. One module has to know about the other, or a third party needs to know about both. If the map and tiles aren't expected to change, it'll simplify development if they have no dependencies on other, more volatile parts of the code. This implies that the views should know about the tiles and/or maps, not vice versa.
The MVC pattern is generally useful in these cases, although the devil will, as always, hide in the details. :)
Monday, February 19, 2007
This topic is archived. No further replies will be accepted.Other recent topics
Powered by FogBugz