2016-05-18 2 views
6

Я понимаю, что поскольку Python имеет первоклассные функции, использование шаблона Strategy обычно является вопросом передачи функции в качестве аргумента и не требуют использования с классами. Но что, если «стратегии» - это не отдельные функции, а скорее группы связанных функций, которые логически должны быть выбраны в качестве набора?Стратегия в Python, когда «стратегия» состоит из более чем одной функции

Мол, вот тривиальный и надуманный пример:

class HexFormatter(object): 
    """Base class for strategies to format hexadecimal numbers.""" 
    pass 

class Motorola(HexFormatter): 
    """Format Motorola style (e.g. $1234)""" 
    @staticmethod 
    def formatbyte(n): 
    return "$%02X" % n 

    @staticmethod 
    def formatword(n): 
    return "$%04X" % n 

class Intel(HexFormatter): 
    """Format Intel-style (e.g. 1234h)""" 
    @staticmethod 
    def formatbyte(n): 
    return "%02Xh" % n 

    @staticmethod 
    def formatword(n): 
    return "%04Xh" % n 

Идея заключается в том вы выбираете стратегию, и вы получите функции для форматирования байтов и функции для форматирования слов в виде набора, а не необходимости указывать их индивидуально. Этот пример сродни тому, как вы это сделаете на языке, таком как C++ (за исключением того, что методы не были бы статичными, потому что вы не можете иметь виртуальные статические методы на C++), и это не так, как если бы он не работал на Python. Но это связано с определением группы «классов», которые имеют только статические методы и не предназначены для инстанцирования, что почему-то кажется не-Pythonic.

Есть ли более идиоматический способ сделать это в Python?

+0

Это необходимость для стратегии быть единым объектом? Если нет, вы можете передавать несколько функций, например. через аргументы ключевого слова или, возможно, передать кортеж или названный набор функций. –

ответ

4

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

Моторола. ру

def formatbyte(n): 
    return "$%02X" % n 

def formatword(n): 
    return "$%04X" % n 

intel.py

def formatbyte(n): 
    return "%02Xh" % n 

def formatword(n): 
    return "%04Xh" % n 

Th как модули являются первоклассными объектами в Python, как вы указали, вы можете просто передать их при использовании своей стратегии.


Другой альтернативой является просто рассмотреть вопрос о принятии каждого элемента стратегии в виде простого параметра функции к тому, что они используются для в коде клиента на основе вашего контекста. Например, вместо того

def some_func(obj): 
    obj.format_byte(...) 
    # other stuff 
    obj.format_word(...) 

Вы не могли бы

def some_func(format_byte, format_word): 
    format_byte(...) 
    # 
    format_word(...) 

В любом случае это не имеет смысла идти по пути ООП, если у вас есть не более, чем статические методы для каждой стратегии - не два экземпляры любого типа будут разными, поскольку нет данных экземпляра.

Смежные вопросы