我理解因为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)
当你在每个策略中有很多功能时,我发现一个很好的选择,虽然对于像这样小的东西可能有点太多,但是在一个单独的模块中定义每个策略
<强> motorola.py 强>
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
然后,正如您所指出的那样,模块是Python中的第一类对象,您可以在使用策略时简单地传递它们。
另一种选择是仅考虑将策略的每个元素作为普通函数参数传递给客户端代码中基于您的上下文使用的任何元素。例如,而不是
def some_func(obj):
obj.format_byte(...)
# other stuff
obj.format_word(...)
你可以
def some_func(format_byte, format_word):
format_byte(...)
#
format_word(...)
在任何情况下,如果每个策略只有静态方法,那么去OOP路由没有意义 - 任何类型的两个实例都没有任何不同,因为没有实例数据。