Как записать Стратегическую модель в Python по-другому, чем пример в Википедии?

Почему вы не используете для этого функцию java:

Если ваши числа маленькие (меньше ваших), вы можете использовать: Integer.parseInt(hex, 16) для преобразования шестнадцатеричной строки в целое число.

  String hex = "ff"
  int value = Integer.parseInt(hex, 16);  

Для больших чисел, подобных вашей, используйте public BigInteger(String val, int radix)

  BigInteger value = new BigInteger(hex, 16);

@ См. JavaDoc:

37
задан martineau 17 December 2015 в 05:01
поделиться

3 ответа

Пример на Python не так уж отличается от других. Чтобы имитировать PHP-скрипт:

class StrategyExample:
    def __init__(self, func=None):
        if func:
             self.execute = func

    def execute(self):
        print("Original execution")

def executeReplacement1():
    print("Strategy 1")

def executeReplacement2():
    print("Strategy 2")

if __name__ == "__main__":
    strat0 = StrategyExample()
    strat1 = StrategyExample(executeReplacement1)
    strat2 = StrategyExample(executeReplacement2)

    strat0.execute()
    strat1.execute()
    strat2.execute()

Вывод:

Original execution
Strategy 1
Strategy 2

Основные отличия:

  • Вам не нужно писать какой-либо другой класс или реализовывать какой-либо интерфейс.
  • Вместо этого вы можете передать ссылку на функцию, которая будет привязаны к нужному методу.
  • Функции все еще можно использовать отдельно, а исходный объект может иметь поведение по умолчанию, если вы хотите (для этого можно использовать шаблон if func == None
  • В самом деле, он чистый, короткий и элегантный, как обычно в Python. Но вы теряете информацию; без явного интерфейса программист считается взрослым, знающим, что они делают.

Обратите внимание, что есть 3 способа динамического добавления метода в Python:

  • Как я вам показал. Но метод будет статическим, он не получит " StrategyExample)

Это свяжет новый метод с strat0 и только с strat0 , как в первом примере. Но start0.execute () получит в качестве аргумента self .

Если вам нужно использовать ссылку на текущий экземпляр в функции, вы должны объединить первый и последний способ. Если вы этого не сделаете:

class StrategyExample:
    def __init__(self, func=None):
        self.name = "Strategy Example 0"
        if func:
             self.execute = func

    def execute(self):
        print(self.name)

def executeReplacement1():
    print(self.name + " from execute 1")

def executeReplacement2():
    print(self.name + " from execute 2")

if __name__ == "__main__":
    strat0 = StrategyExample()
    strat1 = StrategyExample(executeReplacement1)
    strat1.name = "Strategy Example 1"
    strat2 = StrategyExample(executeReplacement2)
    strat2.name = "Strategy Example 2"

    strat0.execute()
    strat1.execute()
    strat2.execute()

Вы получите:

Traceback (most recent call last):
  File "test.py", line 28, in <module>
    strat1.execute()
  File "test.py", line 13, in executeReplacement1
    print self.name + " from execute 1"
NameError: global name 'self' is not defined

Таким образом, правильный код будет:

import sys
import types

if sys.version_info[0] > 2:  # Python 3+
    create_bound_method = types.MethodType
else:
    def create_bound_method(func, obj):
        return types.MethodType(func, obj, obj.__class__)

class StrategyExample:
    def __init__(self, func=None):
        self.name = "Strategy Example 0"
        if func:
             self.execute = create_bound_method(func, self)

    def execute(self):
        print(self.name)

def executeReplacement1(self):
    print(self.name + " from execute 1")

def executeReplacement2(self):
    print(self.name + " from execute 2")

if __name__ == "__main__":
    strat0 = StrategyExample()
    strat1 = StrategyExample(executeReplacement1)
    strat1.name = "Strategy Example 1"
    strat2 = StrategyExample(executeReplacement2)
    strat2.name = "Strategy Example 2"

    strat0.execute()
    strat1.execute()
    strat2.execute()

Это выдаст ожидаемый результат:

Strategy Example 0
Strategy Example 1 from execute 1
Strategy Example 2 from execute 2

Конечно, в случае, если функции больше не могут использоваться отдельно, но все еще может быть привязан к любому другому экземпляру любого объекта без каких-либо ограничений интерфейса.

67
ответ дан 27 November 2019 в 04:02
поделиться

Вы правы, пример из Википедии бесполезен. Он объединяет две вещи:

  1. Стратегию .

  2. Особенности Python, упрощающие реализацию Стратегии . Утверждение «нет необходимости явно реализовывать этот шаблон» неверно. Вам часто нужно реализовать Стратегию , но Python упрощает это, позволяя вам использовать функцию без накладных расходов на оболочку класса вокруг функции.

Во-первых, Стратегия .

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

] Теперь вы можете делать такие вещи.

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

И он будет использовать созданный нами объект стратегии.

Во-вторых, альтернативы Python.

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

Мы можем это сделать.

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

Это также будет использовать предоставленную нами стратегическую функцию. .

32
ответ дан 27 November 2019 в 04:02
поделиться

For clarity, I would still use a 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!"
9
ответ дан 27 November 2019 в 04:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: