We will start with what Strategy design pattern is and then showcase an example on how to define various Strategies
and Context
classes.
Strategy design pattern comes under the category behavioural pattern
. It is also known as Policy pattern. It defines a family of algorithms and encapsulates each algorithm. The algorithm can be interchanged without changing much code. It bury algorithm implementation details in derived classes. It favours composition over inheritance.
Let's take an example of file compression. There are many algorithms that exists which can compress files. We will only focus on zip
and rar
based compression in this example. We first will define the algorithm for Compression in the form of interface and that will have two implementation classes and one context class.
class CompressionStrategy {
void compress(Directory src, Directory destination);
}
class ZipCompresion implements CompressionStrategy {
public void compress(Directory src, Directory destination) {
// zip based compression logic goes here
}
}
class RarCompression implements CompressionStrategy {
public void compress(Directory src, Directory destination) {
// zip based compression logic goes here
}
}
class FileCompressor {
private CompressionStrategy strategy;
public void setCompressionStrategy(CompressionStrategy strategy) {
this.strategy = strategy;
}
public void createArchive(Directory src, Directory destination) {
if (src == null) throw new IllegalArgumentException("Src directory is required");
if (destination == null) throw new IllegalArgumentException("Destination directory is required");
strategy.compress(src, destination);
}
}
Composition is favoured over inheritence in Strategy design pattern. We have composed the CompressionStrategy
in FileCompressor
aka Context class and defined setter method to change the strategy at runtime in FileCompressor
.