lundi 8 février 2021

Can't wrap my head around why replacing conditionals with polymorphism is useful

There's one thing that has always stumped me about "replacing a conditional with polymorphism" as shown on refactoring.guru which I would like to clarify. I have re-created the example in python below:

IF STATEMENT CODE

def get_speed(bird):
    base_speed = 10

    if bird == "AfricanBird":
        return base_speed * 2 - 10
    elif bird=="EuropeanBird":
        return base_speed * 1.85 - 12
    elif bird=="NorwegianBlue":
        return base_speed * 2.5 - 11
    else:
        raise ValueError("Bird type invalid")

if __name__=="__main__":
    b = "EuropeanBird"
    speed = get_speed(b)
    print(speed)

REPLACING IF STATEMENT WITH POLYMORPHISM

from abc import abstractmethod, ABC

class Bird(ABC):
    def get_base_speed(self):
        return 10

    @abstractmethod
    def get_speed(self):
        pass

class AfricanBird(Bird):
    def get_speed(self):
        return self.get_base_speed()*2-10

class EuropeanBird(Bird):
    def get_speed(self):
        return self.get_base_speed()*1.85-12

class NorwegianBlue(Bird):
    def get_speed(self):
        return self.get_base_speed()*2.5-11

if __name__=="__main__":
    # This *still* has to be specified by the user somewhere.
    # For example in a GUI or input text file.
    b = "EuropeanBird"

    # Here is the if statement again!!
    if b == "AfricanBird":
        b = AfricanBird()
    elif b=="EuropeanBird":
        b = EuropeanBird()
    elif b=="NorwegianBlue":
        b = NorwegianBlue()
    else:
        raise ValueError("Bird type invalid")

    print(b.get_speed())

I get the part where polymorphism adds generality by allowing you to inherit from a base class and redefine the behavior instead of adding a new branch in the if statement. However, at the end of the day you still need to make a decision somewhere in your main code for which implementation of your base class to use (line 26 in my second example), which forces the if statement to reappear.

Am I missing the point? Is there any way of completely eliminating the conditional statement in the client code?

Thanks for your help.

Aucun commentaire:

Enregistrer un commentaire