mercredi 28 avril 2021

Appropriate python design pattern

I believe I am facing a subclass explosion problem and would love some guidance..

Let's say we have a major class 'Fruit' derived from Food. Subclasses include Red,Green and Blue Apple. They all have their specific actions that they can do, but are in fact very similar. Current implementation is as follows:

class Fruit(Food):
    def __init__(self, **kwargs):
        super(Food, self).__init__(**kwargs)
        self.version = VERSION

@subclass 
class GreenApple(Fruit):
    def __init__(self, **kwargs):
        super(GreenApple, self).__init__(**kwargs)
        self.position = 0
    
    def jump(self):
        self.position += 10

    ...
@subclass
class RedApple(Fruit):
    def __init__(self, **kwargs):
        super(RedApple, self).__init__(**kwargs)
        self.pieces = 1

    def explode(self):
        self.pieces *= 2
    ... 
@subclass
class BlueApple(Fruit):
    def __init__(self, **kwargs):
        super(BlueApple, self).__init__(**kwargs)

    ...

All three apple classes are very similar and there exists conversion between them (i.e. an event can turn an Apple in to any other Apple subclass). But without a conversion GreenApple can only jump, RedApple can only explode and BlueApple can't do anything yet.

So... what I would like to know is, what kind of implementation would be better? This is of course a part of a larger project, but I tried to simplify it, just to make things clearer.

I was thinking of something like this, but I am afraid I will end up with tons of 'if' statements, which is not pretty either. Any help would be much appreciated.

class Fruit(Food):
    def __init__(self, **kwargs):
        super(Food, self).__init__(**kwargs)
        self.version = VERSION

@subclass 
class Apple(Fruit):
    def __init__(self, **kwargs, type):
        super(Apple, self).__init__(**kwargs)
        self.type = type # red/green/blue
        self.position = 0
        self.pieces = 1
    
    def jump(self):
        if self.type == 'green':
            self.position += 10

    def explode(self):
        if self.type == 'red':
            self.pieces *= 2
    
    def convert(self, type):
        self.type = type

Aucun commentaire:

Enregistrer un commentaire