Python 这是工厂模式的正确实施吗?
首先,这不是家庭作业。第二,它有点长。对不起,谢谢您的耐心等待 有一个。。游戏,基本上它为你提供了一个开始的条件,一个期望的结果,一系列的过程和最大数量的过程。任务是找到正确的流程执行顺序,以获得所需的结果。Python 这是工厂模式的正确实施吗?,python,design-patterns,Python,Design Patterns,首先,这不是家庭作业。第二,它有点长。对不起,谢谢您的耐心等待 有一个。。游戏,基本上它为你提供了一个开始的条件,一个期望的结果,一系列的过程和最大数量的过程。任务是找到正确的流程执行顺序,以获得所需的结果。 所以我认为用计算机来解决这个问题可能是件好事。最大步长通常小于10,因此使用蛮力应该是安全的 下面是我的解决方案代码(顺便说一句,它是用python编写的)。简单地说,我为每个进程创建一个对象,并将它们放入一个列表中。在每个步骤中,我遍历列表,将参数(起始条件、预期结果等)传递给流程对象,
所以我认为用计算机来解决这个问题可能是件好事。最大步长通常小于10,因此使用蛮力应该是安全的 下面是我的解决方案代码(顺便说一句,它是用python编写的)。简单地说,我为每个进程创建一个对象,并将它们放入一个列表中。在每个步骤中,我遍历列表,将参数(起始条件、预期结果等)传递给流程对象,并检查输出是否与预期结果匹配。如果匹配,则返回被调用进程的堆栈
class Puzzle:
def __init__(self, initial_num, num_steps, result, list_process):
self.initial_num = initial_num
self.num_steps = num_steps
self.result = result
self.list_process = list_proces
def solve(self):
for process in self.list_process:
stack = process.run(self.initial_num, self.num_steps, self.result, self.list_process)
if stack is not None:
return stack
return None
对于流程,因为有许多类型的流程,并且在每种情况下都有不同的流程组合要执行。我碰巧使用了一点Java,所以我使用了多态性的思想,这在python中并不是真正需要的,但我认为它是一个整洁的结构
class ProcessBase:
@property
def name(self):
print("need to rewrite")
def do_process(self, num_input):
print("need to rewrite")
def run(self, input_, steps_remain, result, processes_next):
if steps_remain is 0:
return None
try:
output= self.do_process(input_)
except RuntimeError:
return None
if output == result:
stack = [self.name]
return stack
for process in processes_next:
stack = process.run(output, steps_remain - 1, result, processes_next)
if stack is not None:
stack.append(self.name)
return stack
return None
class ProcessA(ProcessBase):
def __init__(self, param):
super().__init__()
self.param = param
@property
def name(self):
return "ProcessA" + self.param
def do_process(self, input):
# do the process(e.g. add 1 to the input)
output = input + 1
return output
所以基本上,run()在每个进程中都是相同的,所以我只需要重写name()来显示调用堆栈,而do_process()用于实际进程。然后我的工厂方法(它不是一个类,因为我认为不需要多个工厂)如下所示
def process_factory(str_input):
if str_input=="A":
return ProcessA()
elif str_input=="B":
return ProcessB()
# etc
因此,在实际使用它时,我可以保持大部分代码不变。当有新类型的进程时,我只需要添加一个新类,覆盖name()和do_process(),在process_factory()方法中添加几行就可以了。但是我仍然没有信心。
我的问题(最后!)是:
例如,假设ProcessA将向输入中添加1,ProcessB将负1。但在ProcessC之后,ProcessA变为加法2,ProcessB变为减法2。我不能直接修改ProcessA,因为原始副本需要在下一个周期中重新使用。 我的解决办法是:
- 添加一个新的ProcessC类并重写run()方法。它对原始代码的更改最少,但有点违背了原始结构的理念
class ProcessBase:
@property
def name(self):
print("need to rewrite")
def do_process(self, num_input):
print("need to rewrite")
def run(self, input_, steps_remain, result, processes_next):
if steps_remain is 0:
return None
try:
output= self.do_process(input_)
except RuntimeError:
return None
if output == result:
stack = [self.name]
return stack
for process in processes_next:
stack = process.run(output, steps_remain - 1, result, processes_next)
if stack is not None:
stack.append(self.name)
return stack
return None
class ProcessA(ProcessBase):
def __init__(self, param):
super().__init__()
self.param = param
@property
def name(self):
return "ProcessA" + self.param
def do_process(self, input):
# do the process(e.g. add 1 to the input)
output = input + 1
return output
正如你所说,一本字典比多个如果更好。您可以通过让类本身拥有值来避免实例化每个对象,这些值在Python中是第一类对象;然后,您可以实例化dict查找的结果:
methods = {'A': [ProcessA, [param1, param2]], 'B', [ProcessB, [param3, param4], ...}
klass, params = methods[str_input]
return klass(*params)
正如你所说,一本字典比多个如果更好。您可以通过让类本身拥有值来避免实例化每个对象,这些值在Python中是第一类对象;然后,您可以实例化dict查找的结果:
methods = {'A': [ProcessA, [param1, param2]], 'B', [ProcessB, [param3, param4], ...}
klass, params = methods[str_input]
return klass(*params)
(1) 我觉得你的实现很好,但我不是专家
对于名称类属性,可以使用\uuuu str\uuu
和\uuu repr\uuu
方法
类ProcessBase:
定义报告(自我):
返回f“{self.\uuuuuu类{uuuuuuu名称}参数:{self.param}”
定义(自我):
返回自我报告__
这样,bo每次都需要重新命名
(2) 如前所述,我还将使用dict
def过程工厂(str输入):
方法={A':进程A,'B',进程B,…}
返回方法[str_input]()
你在拼图中的解题方法成了
def求解(自):
对于self.list\u流程中的流程信:
过程=过程工厂(过程字母)
stack=process.run(self.initial\u num、self.num\u步骤、self.result、self.list\u进程)
如果堆栈不是无:
返回堆栈
一无所获
(3) 您可以使用与以前相同的结构实现ProcessNewBase
以及ProcessNewA
、B
等。在这里,您可以创建一个独特的dict,使用新旧流程。这样,在您的谜题中,您可以设置是否要使用旧流程或新流程,或者甚至实现同时使用这两种流程的解决方案 (1)我觉得您的实现不错,但我不是专家
对于名称类属性,可以使用\uuuu str\uuu
和\uuu repr\uuu
方法
类ProcessBase:
定义报告(自我):
返回f“{self.\uuuuuu类{uuuuuuu名称}参数:{self.param}”
定义(自我):
返回自我报告__
这样,bo每次都需要重新命名
(2) 如前所述,我还将使用dict
def过程工厂(str输入):
方法={A':进程A,'B',进程B,…}
返回方法[str_input]()
你在拼图中的解题方法成了
def求解(自):
对于self.list\u流程中的流程信:
过程=过程工厂(过程字母)
堆栈=进程运行(self.initial\u nu