【问题标题】:Design pattern help设计模式帮助
【发布时间】:2009-12-14 07:42:30
【问题描述】:

我有一些算法要做,它们在很多方面都非常相似,但都不同。

我将尝试举例说明我的意思。

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

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

非常感谢任何 cmets / 建议!谢谢!

【问题讨论】:

  • Robot 类不是此示例中的“基”类。如果是,那就意味着所有这些其他类型的对象都是机器人的一种,如果不是,它们就是机器人的一部分。
  • 是的,你说得有道理。如果只有一件事可以改变,例如手臂,我可以从 Robot 继承并拥有 RobotBlade、RobotRazor 等。但在这种情况下你是对的。

标签: python design-patterns


【解决方案1】:

对于这样的问题,我可能会采用的设计模式是:Dependency Injection 和与之配套的框架、复合模式和构建器模式。它们基本上应该让您将机器人的创建与使用分开。

【讨论】:

  • 从那篇文章中我读到“基本上,不是让您的对象创建依赖项或要求工厂对象为它们创建一个依赖项,而是将所需的依赖项传递给构造函数”。这对我来说似乎很完美。但是我将如何在 python 中实现它呢?我怎样才能让基础看到它有一个由 ArmBlade 类定义的新 MoveArm() 方法,而不是使用它的标准实现? (我假设我的主类有一个 MoveArm())。
  • @吞噬极乐世界:慢点。喘口气。当您说“不同的实现”时,这就是重点。只要所有方法函数具有相同的name,它们就可以有不同的实现。你的复合对象的“moveArm”只是调用了一个 Arm 的“move”,不知道它是什么类型的手臂。
【解决方案2】:

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

【讨论】:

  • 好主意,这具有以通用方式保持多个部件实例状态的优势(超过我的建议)。
  • 这完全是你想要的。您想使用对象组合,也称为“has-a”关系。 robot has-a set of hands, has-a head, etc. 与“is-a”关系形成对比。 RobotBladeHandsRobotHands 的一种。
【解决方案3】:

我不是 Python 人,但快速浏览一下就知道它们支持多重继承,可以像 Java 接口一样使用(Python 似乎不支持接口)。因此,您可以拥有 RobotHand 的基本超类,然后是 RobotHumanHand、RobotBladeHand 等,与您的眼睛、脚一样。这是做你想做的事的合理方式。

【讨论】:

  • 没有。这不是一个好主意。不要在 Python 中使用多重继承。事实上,除非你想重用接口的实现,否则不要使用继承。为了可以互换使用,Python 对象只需要实现兼容的方法,这是一种首选的风格。更像 Smalltalk 而不是 Simula。我的经验是,尝试使用 Simula(或 Java,或 C++)方式在 Python 中使用子类只会让事情变得更加困难。
【解决方案4】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-22
    • 1970-01-01
    • 1970-01-01
    • 2011-01-16
    相关资源
    最近更新 更多