这是工厂模式的正确实现吗?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了这是工厂模式的正确实现吗?相关的知识,希望对你有一定的参考价值。
首先,这不是家庭作业。其次,它有点长。抱歉,谢谢您的耐心配合。
有一个..游戏,基本上它为您提供了开始条件,所需结果,一堆过程和最大过程数。工作是找到正确的执行过程顺序,以便获得所需的结果。因此,我认为使用计算机解决该问题可能会很好。最大步长通常小于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
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()方法中添加几行,就可以了。但是我对此仍然没有信心。我的问题(最终!)是:
- 此实现是否正确,或者在Python中是否过度?
在process_factory()方法中,“ if ... elif ...”变得相当长,我当时正在考虑将其作为字典。如下所示:
方法= {'A':ProcessA(),'B':ProcessB()}
但是这意味着即使不使用它也会创建所有对象。我也可以将dict中的构造函数替换为返回对象的方法,但是当我需要添加另一种类型的Process时,我需要写更多行。有没有更好的方法?
过一会儿,有一种新型的流程,它不会更改输入,但会更改其后的行为方式,这与我当前的设计并不真正兼容。我的解决方案是:
- 添加新的Process类并重写run()方法。它对原始代码所做的更改最少,但是有点违背原始结构的想法。
- 更改整个逻辑,这样一个过程不仅会影响输入,还会影响其他参数(例如可用过程,甚至结果)。但是会有很多更改,我需要考虑如何在创建新的变更版本的过程中维护流程的旧副本。
您认为什么是最好的解决方案?
正如您所说,与多个ifs相比,字典是更好的解决方案。您可以通过使用classses本身的值来避免实例化每个对象,这些值是Python中的一流对象。然后可以实例化dict查询的结果:
methods = {'A': ProcessA, 'B', ProcessB, ...}
return methods[str_input]()
((1)您的实现对我来说似乎不错,但我不是专家。
对于名称类属性,您可以改用__str__
和__repr__
方法。
class ProcessBase:
def __repr__(self):
return f"{self.__class__.__name___} params : {self.param}"
def __str__(self):
return self.__repr__
以这种方式,bo每次都需要重新输入名称。
((2)如前所述,我还将使用字典。
def process_factory(str_input):
methods = {'A': ProcessA, 'B', ProcessB, ...}
return methods[str_input]()
您在难题中的求解方法成为。
def solve(self):
for process_letter in self.list_process:
process = process_factory(process_letter)
stack = process.run(self.initial_num, self.num_steps, self.result, self.list_process)
if stack is not None:
return stack
return None
((3)
以上是关于这是工厂模式的正确实现吗?的主要内容,如果未能解决你的问题,请参考以下文章