设计模式帮助

3

我有一些算法需要完成,它们在许多方面非常相似,但又都不同。

我会尝试举一个例子来说明我的意思。

假设我有一个机器人类。这个类应该是所有类的“基础”。它提供了使机器人在其环境中工作的基本机制。它可能需要自己工作(我是指它可以是抽象类,本身没有用处,或者如果可能的话,具备基本机制以准备工作)。

所有机器人都有手。但有些机器人将拥有类似人类的手,其他机器人将拥有刀片,其他机器人将拥有剃刀。我可以创建一个名为RobotBase的基类,然后创建RobotHumandHand、RobotBladeHand和RobotRazorHand。但它们也可以拥有不同的头、眼睛、腿、手臂等。有没有什么简单的方法可以解决这个问题?我想以类似于乐高的方式来表达,所以我只需定义一个机器人并“添加”我想要的零件。也许通过接口?我甚至不知道Python中是否存在这些(这是我将要使用的语言)。

非常感谢任何评论/建议!谢谢!


2
Robot类在这个例子中不是“基类”。如果是的话,那就意味着所有这些其他类型的对象都是Robot的一种类型,但实际上它们不是,它们只是Robot的一部分。 - Kylotan
是的,你说得对。如果只有一件事情需要改变,比如手臂,我可以从机器人继承并创建RobotBlade、RobotRazor等类。但在这种情况下,你是正确的。 - devoured elysium
4个回答

5

我会选择以下设计模式来解决这个问题:依赖注入和相应的框架、组合模式和建造者模式。它们可以帮助你将机器人的创建和使用分离开来。


从我读到的那篇文章中,它说:“基本上,不是让你的对象创建一个依赖项或要求工厂对象为它们创建一个依赖项,而是将所需的依赖项传递给构造函数。” 这对我来说似乎很完美。但我该如何在Python中实现这一点呢? 我如何使基类看到它具有由ArmBlade类定义的新MoveArm()方法,并且不使用其标准实现?(我假设我的主类具有MoveArm()方法)。 - devoured elysium
@devoured elysium:慢下来,深呼吸。当你说“不同的实现”时,这就是重点。只要所有方法函数具有相同的名称,它们就可以具有不同的实现。你的复合对象的“moveArm”只是调用了一个手臂的“move”,而不知道它是什么类型的手臂。 - S.Lott

4

我认为您的机器人应该有一个端口列表,即每个机器人可能具有的注入组件数量。您的Robot类将是RobotPart的容器。您可以使特定部件具有特定接口。 RobotHand扩展了RobotPart,而Robot类具有一个字段,其中包含RobotHand实现的列表(您可以将其限制为2只手,但在一般情况下可能会更多)。您可以对RobotHead执行相同的操作,它将继承自RobotPart,并且Robot类中将有一个字段,其中包含RobotHead的实现。反过来,RobotHead可能会持有RobotEye实现的列表,依此类推。然后,您特定的Robot实现可以从基类继承其行为,或者利用配置,例如如果可用,使用RobotBladeHand


1
这里有很好的想法,它比我的建议更具优势,可以以通用的方式为多个部件实例保留状态。 - Francis Upton IV
2
这正是你想要的。你想使用对象组合,也称为“拥有”关系。一个机器人拥有一组手,拥有头部等。与“is-a”关系相对比。RobotBladeHandsRobotHands的一种。 - steveha

1
我不是Python专家,但快速查看表明它们支持多重继承,可以像Java接口一样使用(Python似乎不支持接口)。因此,您可以基本上拥有RobotHand的超类,然后是RobotHumanHand、RobotBladeHand等。眼睛、脚等也是如此。这是实现您想要做的事情的合理方法。

3
不,这真的不是一个好主意。 不要在Python中使用多重继承。 实际上,除非你想要重用接口的__implementation__,否则不要使用继承。 为了能够互换使用,Python对象只需要实现兼容的方法即可,这是一种更受欢迎的风格。 更像Smalltalk而不是Simula。 我的经验是,在Python中尝试使用Simula(或Java、C++)的子类使用方式只会让事情变得更加困难。 - Tomek Szpakowicz

0
如果你正在寻找一种设计模式,我建议你选择策略模式。因为实现这个模式,你可以动态地交换机器人的组件。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接