1
52
对我来说 CKing 这篇文章和维基百科中的例子已经很清楚了,但我会尝试给你一个新的例子。正如他们所说,战略模式主要是 一种在运行时改变算法行为的方法 当然,您可以通过许多不同的方式实现这一点(例如保持值和使用switch case,但这不会像Strategy Pattern那样好)。 假设你正在开发一个基于回合的策略游戏 单位 : 步兵 和 坦克 (单位的子类)。你的地形可能是 平原 , 铁路 或 森林 .
任何Unit子类都必须实现 火() 方法,因为 对他们来说会完全不同 (坦克发射重距离子弹,步兵发射数发短距离轻子弹)。在本例中,我们使用普通多态性/继承,因为 火() 对于任何单元,方法都会非常不同,并且 在比赛中它不会改变 .
单位也可以移动,并有一个字段 基本移动 它可以行走的六边形的数量。我们开发的是一个战略游戏,而不是真实世界的模拟,所以我们不关心它们如何移动,我们只想在它们的坐标上添加一个值(在我的示例中,我只使用X坐标,以便获得更简单的代码)。如果所有地形都一样,我们就不需要任何战略目标……但是 我们需要在运行时更改move()方法的行为! 因此,我们实现了不同的 移动策略 类,我们编程游戏以触发 设置移动策略() 在每个六边形上移动的任何单位。我们甚至不需要在Unit子类中编写任何其他内容。
现在,如果有的话 单元 在内部移动 森林 ,我们打电话
一旦它进入 平原 ,我们做到了:
现在我们可以根据地形改变单位移动的距离,而不需要在任何子类中重写。 我希望这有助于您更好地理解差异。 |
2
32
没有方向盘你不能开车。这并不意味着方向盘就是汽车。同样,Strategy模式依赖于多态性,但这并不意味着它们是相同的。 Strategy模式的目的是促进使用组合(has-a)而不是继承(is-a)。您的类不是从超级类继承行为,而是在单独的类中定义行为,并且您的类具有对它的引用。 举个例子,看看 this 答案很好。 |
3
14
|
4
10
如果您正在建立一个类比,其中:
那么不同的是耦合程度,在第一种情况下耦合程度非常强,而在第二种情况下,任何外来代码都可以通过贡献其Strategy实现来参与类的逻辑。 |
5
8
这些问题无疑令人困惑,因为最初这两种想法之间似乎没有任何联系。 多态性在编程中是一个更广泛的概念,是的,Java中的策略模式使用了一种形式的多态性 inclusion polymorphism 实现其目的,但这绝不是唯一存在的多态性类型,也不是实现策略模式的唯一方法,正如我将很快演示的那样。 多态性也不仅仅存在于Java或面向对象编程语言中。不同形式的多态性存在于所有编程范式中,而不是所有语言中,您必须使用多态性来实现策略模式(例如函数语言)。 有关此主题的进一步讨论,请阅读 this other answer 在那里,我们讨论了多态性是否可能没有继承,我为其他类型的多态性提供了有趣的参考和示例,如参数多态性和ad-hoc多态性。 理想情况下,这将向您揭示多态性是一个更大的概念,它超越了面向对象编程的界限,甚至超越了继承和子类型化。
从我的角度来看,这两个概念之间的关系是:策略模式利用Java等语言中可用的多态性的力量来实现其意图,而多态性本身可以被视为一种模式。 例如,考虑GoF书中的这句话:
只是我们很少将多态性视为一种模式,首先是因为它意味着许多事情,因为它在不同语言中的实现方式不同,而且还因为它通常表现为某种形式的语言特征。 杰森·麦克·史密斯(Jason Mc C.Smith)在其著作《元素设计模式》(Elemental Design Patterns)中对GoF的上述引用进行了评论:
因此,正如您所看到的,您正在从Java实现的角度思考Strategy模式,但在其他语言范例中,这种模式可能以不同的方式实现,可能根本不使用继承,例如,在纯函数式编程语言中,这最肯定是使用 high order functions 和 function composition . 因此,这将是一种战略模式的实施,而无需诉诸 包涵体多态性 完全在函数组合策略中,我们可能仍然使用其他形式的多态性(例如参数化),但这不是策略模式的要求
如上所述,在Java中,我们可能被迫使用包含多态性来实现一种策略模式,但正如上面所解释的,模式不是属于特定语言的东西,因此如果我们将策略模式视为一个生活在任何语言边界之外的概念,那么您将很容易看到其他语言以不同的方式实现这一点。 在一些假设的函数语言中,我可能有一个从文件中读取一些数据的函数,可能文件是加密的,您需要提供解密策略:
还有那个
现在你可以了
哪里
像这样工作的语言有几十种,SML、Haskell、JavaScript等。 |
6
3
首先多态性可能意味着两种不同的东西。最常见的多态性是指多态类型。然而,您要求的是模式。 多态代码可以在每次运行时改变自身,而代码的功能保持不变。一个简单的例子是做1+3=4而不是5-1=4。两者都使用不同的代码获得相同的结果。这对于不希望被识别的代码(即计算机病毒或密码)非常有用。 另一方面,策略模式使用一系列可以互换的算法。这可能在翻译文本时使用。首先,一些代码决定了语言。如果语言是瑞典语或西班牙语,则文本将由同一家族的不同函数translateSwedish()或translatePanish()处理。 把事情凑起来。多态代码使用不同的代码实现相同的结果。而Strategy使用不同的代码以获得更好的结果。 |
7
2
考虑一下这个 我们有动物和一个策略模式对象来描述它们如何移动。。。 例如 飞行/游泳/散步 考虑到使用这些方法的动物数量众多(即数千种不同的动物在飞行),我们需要对许多不同的动物使用相同的代码。该代码应该只存在于一个地方,这样就可以很容易地进行更改,并且不会占用任何多余的空间。 在本例中,简单的多态性方法将导致大量代码重复。一种更复杂的方法是在动物和知更鸟之间设置一个中间类,但它没有考虑到动物的移动方式并不是真正的定义。此外,动物可能有其他策略对象,它们不能通过中间类都变成多态的。 |
8
2
多态性的一个定义是向不同类型的实体提供单一接口。 考虑到这一点,假设您有一个bird接口,并且您的所有bird类都必须实现laysEggs()方法,这没什么大不了的。当你继续编写你的鸟天堂程序时,你现在添加了fly(),并意识到企鹅和猕猴桃的重载和重写是不必要的,因为在现实生活中它们不会飞,但你仍然必须实现这个方法。当你面对鸵鸟和其他不会飞的动物时,这可能会变得乏味和毫无意义。在添加方法swim()时更糟糕,因为会游泳的鸟更少。正如您可能已经知道的,策略模式解决了这个问题。 用蹩脚的术语来说,你可以把多态性看作是一个实践的集合体,而战略模式是特定案例的最佳实践。示例:当需要在运行时(通过可互换的算法)选择算法的行为时,将使用策略模式。虽然通过策略模式实现的任何事情基本上都是通过多态性实现的,但如果不了解策略模式,这将使您面临重新发明轮子的问题来解决这个特定问题。总之,即使一个基于另一个,它们也非常不同。 我会让你看Ender Muab'Dib代码,因为它已经很好地解释了,如果你仍然想从我这里得到代码示例,请问我,加油,希望我能帮助你。 |
9
2
多态性是一种原则,策略是一种设计模式 来自oracle文档 page
多态性可以在编译时(方法重载)和运行时(方法重写)实现。
策略可以使用运行时多态性原理来实现所需的功能。 策略模式的URL图中还有一个名为Context的组件。 请参阅以下SE帖子: Real World Example of the Strategy Pattern Does this Java Strategy pattern have a redundant Context class? 几篇更有用的文章: strategy 通过资源制造 |
10
0
以下是简洁的回答:
因此,如果要使用Java(即OOP)实现Strategy模式,那么只需要使用多态性。 换句话说,Strategy模式是多态性的多种形式之一。 |
Venu Chitta · 关于战略模式在铁路中的定位 9 年前 |
TryinHard JohanShogun · 多态性与策略模式 9 年前 |
Mark · 如何通过重写方法来使用javaenum中的字段?[副本] 10 年前 |