My problem is that I have a piece of code logic that I'm having trouble fitting into an OO approach, and I was looking for design patterns so that the following code would no longer rely on the ugly
if class is of type A do X else do Y
In Python, we can say I have three "fighting method" classes,
class Manoeuvre, and
I also have a control class that takes two inputs,
defendMode. The inputs will always be objects whose classes extend from or are of one of the above three.
The piece of script causing issue is as follows:
from random import Random # Following are example "Action" objects which are to be compared # For results class Action: "Base Action all others inherit from" __random = Random() def __init__(self): self.health = 100 @classmethod def getSuccess(cls): return cls.__random.randint(-2,3) class Dodge(Action): def __init__(self): super(Dodge, self).__init__() class Attack(Action): def __init__(self): super(Attack, self).__init__() def performActionOn(self, subject, sucessLevel=0): damage = 5 if successLevel > 1 else 3 subject.health -= damage class Manoeuvre(Action): def __init__(self): super(Manoeuvre, self).__init__() def performActionOn(self, subject, successLevel=0): pass # Following is the results configuration class CombatControl: def fight(self, actionAttack, actionDefend): if isinstance(actionDefend, Dodge): __attackDodge(actionAttack, actionDefend) else: __attackAttack(actionAttack, actionDefend) def __attackAttack(self, attack, defend): """ " Defender Attacks back """ resultAttack = attack.getSuccess() resultDefend = defend.getSuccess() # Both failed. No action. if resultAttack < 0 and resultDefend < 0: return # Attack wins or draw elif resultAttack >= resultDefend: attack.performActionOn(defend, successLevel=resultAttack) # Defend wins else: # Does not get damage bonus defend.performActionOn(attack) def __attackDodge(self, attack, defend): """ " Defender is dodging """ resultAttack = attack.getSuccess() resultDefend = defend.getSuccess() if resultAttack > resultDefend: attack.performActionOn(actionAttack, successLevel=resultAttack)
As you can see in the final case, there's a bit of jiggery-pokery going on where resolution is based upon the type of class. This is undesired.
Ideally I'd want a solution which would allow for something more polymorphic. The structure can change however required if it leads to an elegant solution, as long as the results are the same.