algorithm's behaviour can be selected at runtime.
the strategy pattern defines a family of algorithms, encapsulates each one, and makes
them interchangeable.
Strategy pattern is one of the behavioral design pattern. Strategy
pattern is used when we have multiple algorithm for a specific task and client
decides the actual implementation to be used at runtime.
Strategy pattern is
also known as Policy Pattern. We defines multiple
algorithms and let client application pass the algorithm to be used as a
parameter. One of the best example of this pattern is
Collections.sort() method that takes Comparator parameter. Based on the
different implementations of Comparator interfaces, the Objects are getting
sorted in different ways
public class Student {
private int rollNo;
private String fname;
private String lname;
package strategyP;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
public class TestStudent {
public static void
main(String[] args) {
ArrayList<Student>
studentList = new
ArrayList<Student>();
studentList.add(new Student(1, "Aditya", "Sharma"));
studentList.add(new Student(2, "Beena", "Mishra"));
studentList.add(new Student(3, "Priyanka", "Pandey"));
studentList.add(new Student(4, "Vikas", "Jain"));
studentList.add(new Student(5, "Rose", "Marlo"));
Comparator<Student>
comparasionStrategy
= new
Comparator<Student>() {
@Override
public int compare(Student arg0, Student arg1) {
return
arg0.getFname().compareTo(arg1.getFname());
}
};
Collections.sort(studentList,comparasionStrategy);
for (Student student : studentList) {
System.err.println(student.toString());
}
Collections.sort(studentList,
new
Comparator<Student>() {
@Override
public int compare(Student arg0, Student arg1) {
return arg1.getRollNo() - arg0.getRollNo();
}
});
for (Student student : studentList) {
System.out.println(student.toString());
}
}
}
Where Would I Use This Pattern(A More
Realistic Example)
The Strategy pattern is to be used
where you want to choose the algorithm to use at runtime. A good use of the
Strategy pattern would be saving files in different formats, running various
sorting algorithms, or file compression.
The Strategy pattern provides a way
to define a family of algorithms, encapsulate each one as an object, and make
them interchangeable.
package strategyP;
import java.io.File;
import java.util.ArrayList;
Let's use the example of a file compression
tool - where we create either zip or rar files. First we'll need a strategy:
interface CompressionStrategy {
public void compressFiles(ArrayList<File> files);
}
And we'll need to provide our two implementations, one for
zip and one for rar
class ZipCompressionStrategy implements CompressionStrategy {
public void compressFiles(ArrayList<File> files) {
// using ZIP approach
}
}
class RarCompressionStrategy implements CompressionStrategy {
public void compressFiles(ArrayList<File> files) {
// using RAR approach
}
}
Our context will provide a way for the client to compress the
files. Let's say that there is a preferences setting in our application that
sets which compression algorithm to use. We can change our strategy using the
setCompressionStrategy method in the Context.
class CompressionContext {
private CompressionStrategy strategy;
// this can be set at runtime by the application preferences
public void setCompressionStrategy(CompressionStrategy strategy) {
this.strategy = strategy;
}
// use the strategy
public void createArchive(ArrayList<File> files) {
strategy.compressFiles(files);
}
}
It's obvious that all the client has to do now is pass
through the files to the CompressionContext
public class Client {
public static void
main(String[] args) {
CompressionContext ctx
= new
CompressionContext();
// we could assume context is already set by preferences
ctx.setCompressionStrategy(new ZipCompressionStrategy());
// get a list of files
ArrayList<File>
fileList = null;
ctx.createArchive(fileList);
}
}
This example shows the WarStrategy
package strategyP;
interface WarStrategy {
void strategyDisc();
}
class Surprise implements WarStrategy {
@Override
public void strategyDisc() {
System.out.println("Surprise
your enemies");
}
}
class Maneuver implements WarStrategy {
@Override
public void strategyDisc() {
System.out
.println("Place the enemy in a disadvantageous position through the flexible
application of combat power");
}
}
class Guerrilla implements WarStrategy {
@Override
public void strategyDisc() {
System.out
.println("Lure your opponent to attack to use guerrilla tactics
effectively.");
}
}
public class War {
WarStrategy strategy;
public WarStrategy getStrategy() {
return strategy;
}
public void setStrategy(WarStrategy strategy) {
this.strategy = strategy;
}
public static void
main(String[] args) {
War worldWarI = new War();
worldWarI.setStrategy(new Surprise());
worldWarI.getStrategy().strategyDisc();
War worldWarII = new War();
worldWarII.setStrategy(new Guerrilla());
worldWarII.getStrategy().strategyDisc();
War worldWarIII = new War();
worldWarIII.setStrategy(new Maneuver());
worldWarIII.getStrategy().strategyDisc();
}
}