What is the difference between the Strategy
pattern and Polymorphism
in Java?
I\'m confused that whatever is achieved via Strategy Pattern is
If you are establishing an analogy where:
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.
Q: What is the difference between the Strategy pattern and Polymorphism in 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 polymorphism to 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.
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).
For further discussion on this topic please read this other answer where 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.
For instance, consider this quote from the GoF book:
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:
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.
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 functions and function composition.
As such, this would be an strategy pattern implementation without resorting to inclusion polymorphism at 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.
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 decrypt
argument is a function that serves the purpose of a strategy pattern, it encapsulates an interchangeable algorithm.
Now you can do
readFile("customers.txt", aes)
readFile("finance.txt", blowfish)
Where aes
and blowfish
are decryption function strategies.
There are dozens of languages that work like this, SML, Haskell, JavaScript, etc.
Polymorphism is a principle and Strategy is a design pattern
From oracle documentation page
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.
Polymorphism can be achieved in compile time ( method overloading) and run time (method overriding).
Strategy_pattern
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:
Real World Example of the Strategy Pattern
Does this Java Strategy pattern have a redundant Context class?
Few more useful articles:
strategy by sourcemaking
Here is the concise response:
Therefore, if you are going to implement Strategy pattern by using Java, that is OOP, then you just need to use polymorphism.
In other words, Strategy pattern is one of many forms of polymorphism.
For me, the link from CKing post 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).
Let's say you're developing a turn-based strategy game with two kind of Units: Infantry and Tank (subclasses of Unit). Your terrain could be Plains, Railroad or 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.
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 baseMovement that 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!
So, we implement a different MovementStrategy class 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.
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 Unit move inside a Forest, we call
unit.setMovementStrategy(new ForestMovementStrategy());
And as soon it goes to a Plain, we do:
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.
Polymorphism vs Strategy pattern with core java examples
Basic difference : Polymorphism is programming language concept, and Strategy pattern is one of behavioral design pattern of GoF.
Polymorphism is 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, Polymorphism implemented in two ways:
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 pattern defines a set of algorithms that can be used interchangeably.
Example of core java: java.util.Comparator#compare()
, executed by among others Collections#sort()
.
Modes of transportation is analogous to strategy design pattern. We use car, bike, bus, local train and so on.. different strategies to go office day by day.