[Tutor] Location of object instance in a list

Magnus Lycka magnus@thinkware.se
Thu Oct 31 04:55:01 2002


At 22:41 2002-10-30 -0600, Christian Wyglendowski wrote:
>Now, let's say that I actually did append a 'Cool object instance' to 
>test.surface[0][0] and not just a string by the same name.  Is there 
>anyway the said object instance can have knowledge of its place in the 
>list of lists (test.surface[x][y])?  If so, I can then give the objects 
>the ability to move around the Board.surface[x][y] fairly easily.

Not by itself, no. An object knows what it has, but
it doesn't know where there are references to it.
This is the way we want things. It's part of the
separation of concern that we want to achieve in
computer programs.

If we want a two-directional "awareness" about
relations, we have to make this explicit.

One way to solve this, is to make the board an
attribute of the CoolObject, and to let the board
handle moves.

class CoolObject:
     def __init__(self, board, name):
         self.board = board
         self.name = name
     def move(self, direction):
         self.board.move(direction, self)

Then in the Board class you could do:

     test.surface[0][0].append(CoolObject(self, 'Black Queen'))

and have the method:
     def move(self, direction, pawn):
         directions = {'up': (0,-1), 'down': (0,1),
                       'left': (-1,0), 'right': (1,0)}
         assert direction in directions.keys()
         x,y = self.findPawn(pawn) # Left to you...
         newX, newY = x + directions[direction][0], \
                      y + directions[direction][1]
         if self.availableLocation(newX, newY):
             self.surface[x,y].remove(pawn)
             self.surface[newX,newY].append(pawn)

Of course, it you only have one board, the board instance
could be a global variable, but I think you have memory
enough in your compute to keep a reference in every pawn...

Anyway, built like this, the only thing the CoolObject
class needs to know about movement are which directions
there is, and that's fairly simple to change. This means
that you can change a lot in the design and implementation
of the Board without having to change the CoolObject class.

Depending on the game, it might turn out that the CoolObject
needs to know a lot about it's surroundings to be able to
decide its moves. But is should then be able to get this
information in a generic fashion from public methods and
attributes in the Board class.

Another option would be to have a separate "controller"
object handle the movements, but I don't really like
that style of programming. Mr UseCase, Ivar Jacobson
of Rational, RUP and UML fame advocates this style
with separate controller and entity objects, but I feel
that this separation usually leads to a style of
programming which fails to bring out the advantage of
an object-oriented approach.



-- 
Magnus Lycka, Thinkware AB
Alvans vag 99, SE-907 50 UMEA, SWEDEN
phone: int+46 70 582 80 65, fax: int+46 70 612 80 65
http://www.thinkware.se/  mailto:magnus@thinkware.se