The Design of Software (CLOSED)

A public forum for discussing the design of software, from the user interface to the code architecture. Now closed.

The "Design of Software" discussion group has been merged with the main Joel on Software discussion group.

The archives will remain online indefinitely.

Hypothetical design scenario

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?
Steven Miller Send private email
Sunday, February 18, 2007
 
 
class TileInfo
{
 Tile m_tile;
 Point m_tileLocation;
}

interface IRenderStrategy
{
 void renderTile(TileInfo tileInfo);
}

class Map
{
 List<TileInfo> m_tileCollection;
 void renderMap(IRenderStrategy renderStrategy)
 {
  foreach (TileInfo tileInfo in this.m_tileCollection)
  {
  renderStrategy.renderTile(tileInfo);
  }
 }
}
Christopher Wells Send private email
Sunday, February 18, 2007
 
 
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:

Intent

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.
Chris Tavares Send private email
Sunday, February 18, 2007
 
 
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.
Steven Miller Send private email
Monday, February 19, 2007
 
 
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=
Christopher Wells Send private email
Monday, February 19, 2007
 
 
Have you looked up Model-View-Controller (MVC)?
DJ Clayworth
Monday, February 19, 2007
 
 
Is this for school?
xampl Send private email
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. :)
R
Monday, February 19, 2007
 
 

This topic is archived. No further replies will be accepted.

Other recent topics Other recent topics
 
Powered by FogBugz