1

My simulation model contains agents on a surface. Agent's are represented by class Agent, their locations by class Point, and the surface itself by class Surface. Each point is really just a pair of numbers.

To model an agent's movement, I need to know which surface he's on (e.g., on a torus, he would never hit a land's end, but on a cylinder, he will.)

My question is whether I should add to class Point, as an instance attribute, a reference to the Surface object.

If I do, class Point becomes more complicated, and efficiency suffers (instead of dealing with pairs of numbers, I'll be dealing with pairs of numbers plus a reference). This is especially annoying since there's only one instance of class Surface ever instantiated in a single program run.

If I don't, I would not be able to give class Agent a move method. Instead I'd have to model agents' movement from an outer class that is aware of both the surface and individual agents. This approach seems logically less appealing.

max
  • 49,282
  • 56
  • 208
  • 355
  • Can you not store information about the surface in `Agent`? That seems like the most natural approach to me... – senderle Jan 31 '11 at 08:51
  • actually I misread the post and thought that's what he meant. Adding to Point seems odd... – Spacedman Jan 31 '11 at 08:54
  • Yes yes, adding to Agent is perfectly fine. The choice is really whether keeping redundant information is ok here. – max Jan 31 '11 at 09:13
  • Well I think when you have a number of interlinked classes like this, some redundancy of this kind is unavoidable. But it's just a reference -- they're cheap. The question to ask is, where does the information belong? Since the information is necessary to give `Agent` a move method, it belongs with `Agent`. – senderle Jan 31 '11 at 09:16

1 Answers1

1

I'm not sure why adding an extra attribute is an efficiency problem - it won't affect the speed and it'll only increase the size of the object by 10 bytes or so. So unless you are dealing with millions of Agents (Missterrr Annnderssssonnn) I wouldn't worry about it.

You could alternatively have a single Surface which is created in a module as a local and accessed via a module method (a bit cleaner than a global). So something like:

 import TheSurface
 class Agent:
  ...
   def Move(self,x,y):
     surface = TheSurface.getSurface()
     surface.canIMoveTo(x,y)
     ....

TheSurface.py would have some kind of initialisation method that created the surface, which would need to be called at program start. @DesignPattern people: is this a 'singleton' pattern?

Creating an Agent with a Surface and storing it as an attribute is a better way. I don't see why you'd add it to a Point though.

The structure is something like:

  • An Agent is on a Surface
  • An Agent is at a Point

Hence you can deduce that the Point is on the Surface, and there's no need to model that separately, unless perhaps you might be dealing with Points that aren't involved in some way to Agents, but then you will have the context of a Surface anyway. It'll always be "Right, now I have to put some Trees on this surface - createTree(surface,point)" etc. Anything on the surface has a surface and a point.

Spacedman
  • 92,590
  • 12
  • 140
  • 224
  • Yeah that's a singleton -- but I don't see the point of making a singleton here. – senderle Jan 31 '11 at 08:56
  • True. Just create the Agent with a Surface object. The OP didnt want to add a Surface attribute to Point, so I've not added a Surface attribute to Agent. It would be the better way. I'll emend... – Spacedman Jan 31 '11 at 09:01
  • Thanks for the answer. I have a related question, but it's too big to put in comments, so it's here: http://stackoverflow.com/questions/4860686/where-in-class-hierarchy-should-instance-methods-be-written. – max Feb 01 '11 at 09:09