java 多态 vs 策略模式

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31608902/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 18:51:46  来源:igfitidea点击:

Polymorphism vs Strategy pattern

javadesign-patternspolymorphismstrategy-pattern

提问by TryinHard

What is the difference between the Strategypattern and Polymorphismin Java?

Strategy模式和PolymorphismJava 中的模式有什么区别?

I'm confused that whatever is achieved via Strategy Pattern is basically possible by polymorphism. Correct me if I'm wrong in this regard.

我很困惑,通过策略模式实现的任何东西基本上都可以通过多态实现。如果我在这方面错了,请纠正我。

Please, also provide me example to eradicate my confusion.

请也给我提供一个例子来消除我的困惑。

采纳答案by rolgalan

For me, the link from CKingpost and the example in Wikipedia are clear enough, but I'll try to give you a new example. As they said, Strategy Pattern is mostly a way to change the behaviour of an algorithm at runtime. Of course you can achieve this in many different ways (such as holding a value and using switch-case, but it wouldn't be as nice as Strategy Pattern).

对我来说,来自CKing帖子的链接和维基百科中的示例已经足够清楚了,但我会尝试给你一个新的例子。正如他们所说,策略模式主要是一种在运行时改变算法行为的方法。当然,您可以通过许多不同的方式来实现这一点(例如持有一个值和使用 switch-case,但它不会像策略模式那样好)。

Let's say you're developing a turn-based strategy game with two kind of Units: Infantryand Tank(subclasses of Unit). Your terrain could be Plains, Railroador Forests.

假设您正在开发具有两种单位的回合制战略游戏:步兵坦克(单位的子类)。您的地形可以是平原铁路森林

class Unit{
    MovementStrategy ms;      
    final int baseMovement;
    int x,y;

    public Unit(int baseMovement){
        this.baseMovement = baseMovement;
    }

    abstract void fire();

    void moveForward(){
        x = x + ms.getHexagonsToMove(baseMovement);
    }

    void setMovementStrategy(MovementStrategy ms){
        this.ms = ms;
    }
}

Any Unit subclass must implement fire()method because it's going to be completely different for them(Tank shots heavy long-distance round and Infantry shot several short distance light bullets). In this example we use normal polymorphism/inheritance since fire()method will be really different for any unit, and it won't change during the game.

任何 Unit 子类都必须实现fire()方法,因为它对它们来说将是完全不同的(坦克射击重型长距离子弹和步兵射击几个短距离轻型子弹)。在这个例子中,我们使用了普通的多态/继承,因为fire()方法对于任何单位来说都是不同的,并且在游戏过程中不会改变

class Infantry extends Unit{
    public Infantry(){
        super(2);
    }

    void fire(){
        //whatever
    }
}

class Tank extends Unit{
    public Tank(){
        super(5);
    }

    void fire(){
        //whatever
    }
}

Units also are able to move, and have a field baseMovementthat holds the number of hexagons it can walk. We're developing a strategy game, not a real world simulation, so we don't care how they move, we just want to add a value to their coordinates (in my example I only use X coordinate in order to get a simpler code). If all the terrain was the same, we wouldn't need any Strategy object... but we need to change the behaviour of move() method at runtime!

单位也可以移动,并且有一个字段baseMovement来保存它可以行走的六边形数量。我们正在开发一个策略游戏,而不是真实世界的模拟,所以我们不关心他们如何移动,我们只想给他们的坐标添加一个值(在我的例子中我只使用 X 坐标以获得更简单的代码)。如果所有地形都相同,我们就不需要任何 Strategy 对象……但是我们需要在运行时更改 move() 方法的行为!

So, we implement a different MovementStrategyclass for each of our kinds of Terrain, and we program our game to trigger a setMovementStrategy()to any unit that move on each hexagon. And we don't even need to write anything else in our Unit subclasses.

因此,我们为每种地形实现了不同的MovementStrategy类,并且我们对游戏进行编程以触发setMovementStrategy()到在每个六边形上移动的任何单位。我们甚至不需要在我们的 Unit 子类中编写任何其他内容。

interface MovementStrategy{
    public int getHexagonsToMove(int base);
}

class PlainMovementStrategy implements MovementStrategy{
    public int getHexagonsToMove(int base){
        return base;
    }
}

class RailroadMovementStrategy implements MovementStrategy{
    public int getHexagonsToMove(int base){
        return base*3;
    }
}

class ForestMovementStrategy implements MovementStrategy{
    public int getHexagonsToMove(int base){
        return (int)(base/2);
    }
}   

Now, when any Unitmove inside a Forest, we call

现在,当任何单位Forest内移动时,我们调用

unit.setMovementStrategy(new ForestMovementStrategy());

And as soon it goes to a Plain, we do:

一旦它进入一个Plain,我们就会:

unit.setMovementStrategy(new PlainMovementStrategy());

Now we're able to change how far away our units move depending on the Terrain, and we don't need to rewrite in any of the subclasses.

现在我们可以根据地形改变我们的单位移动的距离,而且我们不需要在任何子类中重写。

I hope this helps you a better understanding of the difference.

我希望这可以帮助您更好地了解差异。

回答by CKing

I'm confused that whatever is achieved via Strategy Pattern is basically possible by polymorphism.

我很困惑,通过策略模式实现的任何东西基本上都可以通过多态实现。

You can't drive a car without a steering wheel. That does not mean that a steering wheel is a car. Similarly, the Strategy pattern relies on polymorphism but that does not mean that they are the same thing.

没有方向盘就不能开车。这并不意味着方向盘就是汽车。同样,策略模式依赖于多态性,但这并不意味着它们是一回事。

The purpose of the Strategy pattern is to promote the use of composition (has-a) over inheritance (is-a). Instead of your class inheriting behavior from a super class, you define the behavior in a separate class and your class has-a reference to it.

策略模式的目的是促进使用组合(has-a)而不是继承(is-a)。您的类不是从超类继承行为,而是在单独的类中定义行为,并且您的类具有对它的引用。

As far as an example goes, take a look at thisanswer that does a good job.

就一个例子而言,看看这个做得很好的答案。

回答by Premraj

Polymorphism vs Strategy pattern with core java examples

多态与策略模式与核心 Java 示例

  • Basic difference : Polymorphismis programming language concept, and Strategy patternis one of behavioral design pattern of GoF.

  • Polymorphismis the provision of a single interface to entities of different types.
    Example:The steering wheel(i.e., the interface) is same no matter what type of actual steering mechanism is used. That is, the steering wheel works the same whether your car has manual steering, power steering, or rack-and-pinion steering. Therefore once you know how to operate the steering wheel, you can drive any type of car.

  • In programming, Polymorphismimplemented in two ways:

    • Early-Binding/Static/Compile-Time Polymorphism (ex: function overloading)
    • Late-Binding/Dynamic/Run-Time Polymorphism (ex: function overriding)
  • 基本区别:多态是编程语言的概念,策略模式GoF行为设计模式之一

  • 多态性是为不同类型的实体提供单一接口。
    示例:无论使用何种类型的实际转向机构,方向盘(即接口)都是相同的。也就是说,无论您的汽车是手动转向、动力转向还是齿轮齿条转向,方向盘的工作方式都是一样的。因此,一旦您知道如何操作方向盘,您就可以驾驶任何类型的汽车。

  • 在编程中,多态有两种实现方式:

    • 早期绑定/静态/编译时多态性(例如:函数重载)
    • 后期绑定/动态/运行时多态性(例如:函数覆盖)

Compile-time: the time period in which you, the developer, are compiling your code.
Run-time: the time period which a user is running your piece of software.
Source

编译时间:开发人员编译代码的时间段。
运行时间:用户运行您的软件的时间段。
来源

  • A Strategy patterndefines a set of algorithms that can be used interchangeably.

    • The Strategy pattern is a dynamic pattern (How do you want run a behavior in software?).
    • Example of core java: java.util.Comparator#compare(), executed by among others Collections#sort().

    • Modes of transportationis analogous to strategy design pattern. We use car, bike, bus, local train and so on.. different strategies to go office day by day.

  • 策略模式定义了一组可被可互换地使用的算法。

    • 策略模式是一种动态模式(您希望如何在软件中运行行为?)。
    • 核心 java: 的示例java.util.Comparator#compare(),由其他人执行Collections#sort()

    • 运输方式类似于策略设计模式。我们每天使用汽车、自行车、公共汽车、当地火车等等……不同的策略去上班。

回答by Edwin Dalorzo

Q:What is the difference between the Strategy pattern and Polymorphism in Java?

问:Java 中的策略模式和多态有什么区别?

The questions is certainly confusing since initially there seems not to be any relation between these two ideas.

这些问题肯定令人困惑,因为最初这两个想法之间似乎没有任何关系。

Polymorphism is a much broader concept in programming and yes the strategy pattern in Java uses a form of polymorphism catalogued as inclusion polymorphismto accomplish its intent, but this is by no means the only type of polymorphism that exists, neither it is the only way to implement the strategy pattern as I will demonstrate soon.

多态在编程中是一个更广泛的概念,是的,Java 中的策略模式使用一种被归类为包含多态的多态形式来实现其意图,但这绝不是存在的唯一多态类型,也不是唯一的方法实施我将很快演示的策略模式。

Also polymorphism is not something that only exists in Java or in object-oriented programming languages. Different forms of polymorphism exist in all the programming paradigms and not in all languages you are forced to use polymorphism to implement a strategy pattern (e.g. functional languages).

此外,多态性不仅仅存在于 Java 或面向对象的编程语言中。不同形式的多态存在于所有的编程范式中,并不是在所有被迫使用多态来实现策略模式的语言中(例如,函数式语言)。

For further discussion on this topic please read this other answerwhere we have discussed whether polymorphism is possible without inheritance and I provide interesting references and examples to other types of polymorphism like parametric and ad-hoc polymorphism.

有关此主题的进一步讨论,请阅读另一个答案,其中我们讨论了在没有继承的情况下是否可以实现多态性,并且我提供了其他类型的多态性(如参数多态性和临时多态性)的有趣参考和示例。

Ideally this will reveal to you that polymorphism is a bigger concept that goes beyond the boundaries of object-oriented programming and even beyond inheritance and subtyping.

理想情况下,这将向您揭示多态是一个更大的概念,它超越了面向对象编程的界限,甚至超越了继承和子类型。

Q:I'm confused that whatever is achieved via Strategy Pattern is basically possible by polymorphism. Correct me if I'm wrong in this regard.

问:我很困惑,通过策略模式实现的任何东西基本上都可以通过多态实现。如果我在这方面错了,请纠正我。

From my point of view the relations between these two concepts are: that the strategy pattern leverages the power of polymorphism available in languages like Java to implement its intent, and that polymorphism can be considered in itself a pattern.

在我看来,这两个概念之间的关系是:策略模式利用 Java 等语言中可用的多态性的力量来实现其意图,并且多态性本身可以被视为一种模式。

For instance, consider this quote from the GoF book:

例如,请考虑 GoF 书中的这句话:

If we assumed procedural languages, we might have included design patterns called 'inheritance', 'encapsulation' and 'polymorphism'.

如果我们假设是过程语言,我们可能会包含称为“继承”、“封装”和“多态”的设计模式。

It is just that we rarely think of polymorphism as a pattern, first because it implies many things and because it is implemented differently in different languages and also because it typically presents as some form of language feature.

只是我们很少将多态视为一种模式,首先是因为它暗示了很多东西,并且因为它在不同语言中的实现方式不同,还因为它通常表现为某种形式的语言特征。

In his book Elemental Design Patterns, Jason Mc C. Smith comments on the GoF quote above saying:

Jason Mc C. Smith 在他的 Elemental Design Patterns 一书中评论了上面的 GoF 引用说:

Pattern are language-independent concepts; they take form and become concrete solutions when you implement them within a particular language with a given set of language features and constructs [...] This means that it is a bit strange to talk about "Java design pattern", "C++ design patterns", "Websphere design pattern" and so on, even though we all do it. It's a mildly lazy form of shorthand for what we really mean, or should mean: design patterns as implemented in Java, C++, WebSphere and so on, regardless of language or API.

模式是独立于语言的概念;当您在具有给定语言特性和构造的特定语言中实现它们时,它们会形成并成为具体的解决方案 [...] 这意味着谈论“Java 设计模式”、“C++ 设计模式”有点奇怪”、“Websphere 设计模式”等等,即使我们都这样做。这是我们真正含义或应该含义的一种稍微懒惰的速记形式:在 Java、C++、WebSphere 等中实现的设计模式,而不管语言或 API。

So, as you can see, you are thinking in the Strategy pattern from the perspective of the Java implementation, but in other language paradigms such pattern may have been implemented in different ways, probably without using inheritance at all, for example, in pure functional programming languages this is most certainly implemented using high order functionsand function composition.

因此,如您所见,您正在从 Java 实现的角度考虑策略模式,但在其他语言范式中,这种模式可能以不同方式实现,可能根本不使用继承,例如,在纯函数式中这肯定是使用高阶函数函数组合实现的编程语言。

As such, this would be an strategy pattern implementation without resorting to inclusion polymorphismat all. In a function composition strategy we may still be using other forms of polymorphism (e.g. parametric), but that is not a requirement for the strategy pattern

因此,这将是一种完全不诉诸包含多态性的策略模式实现。在函数组合策略中,我们可能仍然使用其他形式的多态性(例如参数),但这不是策略模式的要求

Q: Please, also provide me example to eradicate my confusion.

问:请也给我举个例子来消除我的困惑。

As discussed above, in Java we are probably forced to use inclusion polymorphism to implement a Strategy pattern, but as explained above as well, patterns are not something that belong to a specific language, so if we think of the strategy pattern as a concept living outside any language boundaries then you will easily see other languages implement this in different ways.

如上所述,在 Java 中,我们可能被迫使用包含多态来实现策略模式,但正如上面所解释的,模式不是属于特定语言的东西,所以如果我们将策略模式视为一个概念在任何语言边界之外,您将很容易看到其他语言以不同的方式实现这一点。

In some hypothetical functional language I may have a function that reads some data from a file, maybe the file is encrypted and you need to provide a decryption strategy:

在一些假设的函数式语言中,我可能有一个从文件中读取一些数据的函数,也许文件是加密的,你需要提供一个解密策略:

function readFile(path: String, decrypt: string -> string) {
    return decrypt(loadFromDisk(path));
}

And that decryptargument is a function that serves the purpose of a strategy pattern, it encapsulates an interchangeable algorithm.

decrypt参数是一个用于策略模式目的的函数,它封装了一个可互换的算法。

Now you can do

现在你可以做

readFile("customers.txt", aes)
readFile("finance.txt", blowfish)

Where aesand blowfishare decryption function strategies.

Whereaesblowfishare 解密函数策略。

There are dozens of languages that work like this, SML, Haskell, JavaScript, etc.

有几十种语言可以像这样工作,SML、Haskell、JavaScript 等。

回答by Marko Topolnik

If you are establishing an analogy where:

如果您正在建立一个类比,其中:

  • in one case you have several overridable methods;
  • in the other case you have a Strategy interface with several implementations,
  • 在一种情况下,您有几种可覆盖的方法;
  • 在另一种情况下,您有一个包含多个实现的 Strategy 接口,

then the difference is the degree of coupling, which is very strong in the first case, whereas in the second case any foreign code can participate in your class's logic by contributing its Strategy implementation.

那么不同之处在于耦合度,这在第一种情况下非常强,而在第二种情况下,任何外部代码都可以通过贡献其 Strategy 实现来参与您的类的逻辑。

回答by Herman Wilén

First of all. Polymorphism can mean two different things. Most commonly polymorphism refers to a polymorphic type. However, you are asking for the pattern.

首先。多态性可能意味着两种不同的东西。最常见的多态性是指多态类型。但是,您要求的是模式。

Polymorphic code can change itself each time it runs while the function of the code stays the same. An easy example is to do 1+3=4 instead of 5-1=4. Both achieves the same result using different code. This is useful for code that does not want to be recognized i.e computer viruses or cryptographic code.

多态代码每次运行时都可以改变自己,而代码的功能保持不变。一个简单的例子是做 1+3=4 而不是 5-1=4。两者都使用不同的代码实现了相同的结果。这对于不想被识别的代码很有用,例如计算机病毒或加密代码。

Strategy pattern on the other hand uses a family of algorithms that can be interchanged. This might be used when translating text. First some code determines the language. if the language is swedish or spanish the text will be processed by, different functions of the same family, translateSwedish() or translateSpanish().

另一方面,策略模式使用一系列可以互换的算法。这可能在翻译文本时使用。首先,一些代码决定了语言。如果语言是瑞典语或西班牙语,文本将被处理,同一家族的不同函数,translateSwedish() 或 translateSpanish()。

To round things up. Polymorphic code uses different code that achieves the same result. While Strategy uses different code to achieve better results.

把事情搞定。多态代码使用不同的代码实现相同的结果。而 Strategy 使用不同的代码来获得更好的结果。

回答by Joshua Byer

Consider this

考虑这个

we have animals and a strategy pattern object to describe how they move... for instance

我们有动物和一个策略模式对象来描述它们如何移动……例如

fly/swim/walk

飞/游泳/步行

Given the large number of animals that use any of these methods (ie thousands of different animals fly), we need to use the same code for many different animals. That code should only exist in one place, so that it is easily changed and doesn't take up any unneeded space.

鉴于使用这些方法中的任何一种的大量动物(即数千种不同的动物飞行),我们需要对许多不同的动物使用相同的代码。该代码应该只存在于一个地方,以便它可以轻松更改并且不会占用任何不需要的空间。

In this example, a straightforward polymorphism approach will result in massive code duplication. A more complex approach which places a intermediate class between animal and say robin fail to take in to consideration that how a animal moves is not really what defines it. Furthermore, it is possible that a animal has other strategy objects and they cannot all be made polymorphic through intermediate classes.

在这个例子中,一个简单的多态方法将导致大量的代码重复。一种更复杂的方法,它在动物和罗宾之间放置一个中间类,没有考虑到动物的移动方式并不是真正定义它的原因。此外,一个动物可能有其他策略对象,并且它们不能通过中间类全部变成多态。

回答by Omar Ayala

One definition for Polymorphism is the provision of a single interface to entities of different types.

多态的一个定义是为不同类型的实体提供单一接口。

With that in mind say you have a “bird” interface and all of your bird classes must implement “laysEggs()” method, well no biggie that works. And as you keep coding your “bird paradise program” you now add the “fly()” and realize that overloading and overriding for penguin and kiwi is unnecessary as in real life they can't fly, yet you must still implement that method. This can become tedious and pointless as you are faced with Ostrich and others that can't fly. And even worst off when adding the method “swim()” because even fewer birds can swim. As you may already know, the strategy pattern solves this problem.

考虑到这一点,假设您有一个“鸟”接口,并且您所有的鸟类都必须实现“laysEggs()”方法,这没什么大不了的。当您继续编写“鸟类天堂程序”时,您现在添加了“fly()”并意识到企鹅和猕猴桃的重载和覆盖是不必要的,因为在现实生活中它们不能飞,但您仍然必须实现该方法。当您面对鸵鸟和其他不会飞的动物时,这会变得乏味且毫无意义。添加方法“swim()”时情况更糟,因为会游泳的鸟更少。您可能已经知道,策略模式解决了这个问题。

In lame-man's terms you can think of Polymorphism as a conglomerate of practices, while the Strategy Pattern is the best practice for a specific case. Example: the Strategy Pattern is to be used when an algorithm's behavior needs to be selected at Runtime (via interchangeable algorithms). And although it is sort of true that whatever is achieved via Strategy Pattern is basically possible by polymorphism, without knowledge of the Strategy Pattern this would leave you with the “reinvent the wheel” problem to solve this specific problem. In conclusion, they are very different even if one is based on the other. I'll leave you to see “Ender Muab'Dib” code as it is well explained if you still want a code example from me just ask, cheers and hope I helped.

用蹩脚的人的话来说,您可以将多态性视为实践的集合,而策略模式是特定情况下的最佳实践。示例:当需要在运行时(通过可互换算法)选择算法的行为时,将使用策略模式。虽然通过策略模式实现的任何事情基本上都可以通过多态实现,但如果不了解策略模式,这会给你留下“重新发明轮子”的问题来解决这个特定问题。总之,即使一个基于另一个,它们也是非常不同的。我会让你看到“Ender Muab'Dib”代码,因为它解释得很好,如果你仍然想要我的代码示例,就问吧,干杯,希望我有所帮助。

回答by Ravindra babu

Polymorphism is a principle and Strategy is a design pattern

多态是原则,策略是设计模式

From oracle documentation page

来自 oracle 文档页面

The dictionary definition of polymorphism refers to a principle in biology in which an organism or species can have many different forms or stages. This principle can also be applied to object-oriented programming and languages like the Java language. Subclasses of a class can define their own unique behaviors and yet share some of the same functionality of the parent class.

多态性的字典定义是指生物学中的一个原则,其中一个生物体或物种可以有许多不同的形式或阶段。这个原则也可以应用于面向对象的编程和像 Java 语言这样的语言。一个类的子类可以定义它们自己独特的行为,同时共享父类的一些相同功能。

Polymorphism can be achieved in compile time ( method overloading) and run time (method overriding).

多态可以在编译时(方法重载)和运行时(方法重载)实现。

Strategy_pattern

策略模式

  1. Defines a family of algorithms,
  2. Encapsulates each algorithm, and
  3. Makes the algorithms interchangeable within that family.
  1. 定义了一系列算法,
  2. 封装每个算法,和
  3. 使算法在该系列中可互换。

Strategy can use run-time polymorphism principle to achieve the desired functionality.

策略可以使用运行时多态性原理来实现所需的功能。

Strategy pattern had one more component called Context in it's URL diagram. Refer to below SE posts:

策略模式在它的 URL 图中还有一个名为 Context 的组件。请参阅以下 SE 帖子:

Real World Example of the Strategy Pattern

策略模式的真实世界示例

Does this Java Strategy pattern have a redundant Context class?

这个 Java 策略模式是否有一个冗余的 Context 类?

Few more useful articles:

更多有用的文章:

strategyby sourcemaking

源头策略