web-dev-qa-db-fra.com

Comment écrire un modèle de stratégie dans Python Différemment que par exemple dans Wikipedia?

Dans l'entrée Wikipedia de 2009 pour la structure de stratégie, il existe un exemple écrit en PHP .

La plupart des autres échantillons de code font quelque chose comme:

a = Context.new(StrategyA.new)
a.execute #=> Doing the task the normal way

b = Context.new(StrategyB.new)
b.execute #=> Doing the task alternatively

c = Context.new(StrategyC.new)
c.execute #=> Doing the task even more alternative

Dans le Python code une technique différente est utilisé avec un bouton Soumettre. Je me demande ce que le Python code ressemblera également si cela l'a également fait la façon dont il l'a également fait la façon dont il l'a aussi fait Les échantillons de code font.

Mise à jour: Peut-il être plus courte à l'aide de fonctions de première classe dans Python?

39
nonopolarity

Répondre à une ancienne question pour les Googlers qui ont cherché "Python Strategy Modèle" et atterri ici ...

Ce modèle est pratiquement inexistant dans les langues prenant en charge les fonctions de première classe. Vous voudrez peut-être envisager de profiter de cette fonctionnalité à Python:

def strategy_add(a, b):
    return a + b

def strategy_minus(a, b):
    return a - b

solver = strategy_add
print solver(1, 2)
solver = strategy_minus
print solver(2, 1)

Cette approche est très propre et simple.

Aussi, assurez-vous de consulter Joe Gregorio's Pycon 2009 Talk de Python et des modèles de conception (ou manque de celui-ci): http://pyvideo.org/video/146/pycon- 2009 - Le manque de modèles de design-in-Pyth

44
Christian Groleau

Vous avez raison, l'exemple Wikipedia n'est pas utile. Il confond deux choses.

  1. Stratégie.

  2. Caractéristiques de Python qui simplifie la mise en œuvre de -stratégie. Le "Il n'est pas nécessaire de mettre en œuvre ce modèle explicitement" est incorrect. Vous devez souvent mettre en œuvre Stratégie, mais Python simplifie ceci en vous permettant d'utiliser une fonction sans la surcharge d'une enveloppe de classe autour d'une fonction.

Premièrement, Stratégie.

class AUsefulThing( object ):
    def __init__( self, aStrategicAlternative ):
        self.howToDoX = aStrategicAlternative
    def doX( self, someArg ):
        self. howToDoX.theAPImethod( someArg, self )

class StrategicAlternative( object ):
    pass

class AlternativeOne( StrategicAlternative ):
    def theAPIMethod( self, someArg, theUsefulThing ):
        pass # an implementation

class AlternativeTwo( StrategicAlternative ):
    def theAPImethod( self, someArg, theUsefulThing ):
        pass # another implementation

Maintenant, vous pouvez faire des choses comme ça.

t = AUsefulThing( AlternativeOne() )
t.doX( arg )

Et cela utilisera l'objet de stratégie que nous avons créé.

Deuxièmement, Python Alternatives.

class AUsefulThing( object ):
    def __init__( self, aStrategyFunction ):
        self.howToDoX = aStrategyFunction
    def doX( self, someArg ):
        self.howToDoX( someArg, self )

def strategyFunctionOne( someArg, theUsefulThing ):
        pass # an implementation

def strategyFunctionTwo( someArg, theUsefulThing ):
        pass # another implementation

Nous pouvons le faire.

t= AUsefulThing( strategyFunctionOne )
t.doX( anArg )

Cela utilisera également une fonction de stratégie que nous avons fournie.

33
S.Lott

Pour plus de clarté, j'utiliserais toujours une pseudo-interface:

class CommunicationStrategy(object):
    def execute(self, a, b):
        raise NotImplementedError('execute')

class ConcreteCommunicationStrategyDuck(CommunicationStrategy):
    def execute(self, a, b):
        print "Quack Quack"

class ConcreteCommunicationStrategyCow(CommunicationStrategy):
    def execute(self, a, b):
        print "Mooo"

class ConcreteCommunicationStrategyFrog(CommunicationStrategy):
    def execute(self, a, b):
        print "Ribbit! Ribbit!"
10
Nicolas Dumazet

J'ai essayé de convertir l'exemple de "Duck" à partir du 1er chapitre (motif de la stratégie de couverture) de Tête de modèle de conception en Python:

class FlyWithRocket():
    def __init__(self):
        pass
    def fly(self):
        print 'FLying with rocket'

class FlyWithWings():
    def __init__(self):
        pass
    def fly(self):
        print 'FLying with wings'

class CantFly():
    def __init__(self):
        pass
    def fly(self):
        print 'I Cant fly'

class SuperDuck:
    def __init__(self):
        pass
    def setFlyingBehaviour(self, fly_obj):
        self.fly_obj = fly_obj
    def perform_fly(self):
        self.fly_obj.fly()

if __name__ == '__main__':
    duck = SuperDuck()
    fly_behaviour = FlyWithRocket()
    #fly_behaviour = FlyWithWings()
    duck.setFlyingBehaviour(fly_behaviour)
    duck.perform_fly()
2
Saurabh Verma