Question

Here's a toy problem dealing with multiple composition:

There are two object classes, representing marbles and boxes. A Marble is always contained in a Box, and a Box has a class method for representing the marbles that are currently in it. A Marble, once instantiated, should be capable of being passed to any other existing Box (or maybe even another object for extensibility).

What are the best patterns for implementing multiple 'has-a' composition in Python? (I've found single has-a examples, but didn't stumble across a multiple composition example).

My first guess, whatever it's worth, is to handle the Marble objects through methods contained in the Box class (e.g. create_marble, pass_marble, delete_marble methods) and maintain a list of Marbles as an attribute in the Box class. But is that really the best way to do this?

Was it helpful?

Solution

class Marble(object):
    def __init__(self,color=None):
        self.color=color # I'm assuming this is necessary,
                         # just because "colored marbles in
                         # a box" is so typical
    def __repr__(self):
        return "Marble({})".format(self.color)

class Box(object):
    def __init__(self,name=None,marbles=None):
        self.name = name
        if marbles is None:
            marbles = list()
        self.marbles = marbles
    def addMarble(self,color=None):
        self.marbles.append(Marble(color))
    def giveMarble(self,other):
        # import random
        index = random.randint(0,len(self.marbles)-1)
        try:
            other.marbles.append(self.marbles.pop(index))
        except AttributeError:
            raise NotImplementedError("Can't currently pass marbles to an "
                                      "object without a marbles list")
    def __str__(self):
        return '\n'.join([str(marble) for marble in self.marbles])

a = Box()
b = Box()
for _ in range(10): a.addMarble()
print(a)
# Marble(None)
# Marble(None)
# Marble(None)
# Marble(None)
# Marble(None)
# Marble(None)
# Marble(None)
# Marble(None)
# Marble(None)
# Marble(None)
a.giveMarble(b)
print(b)
# Marble(None)

OTHER TIPS

Yes it is, composition means that the owner object (Box) is responsible for create and destroy the owned objects (Marble).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top