Easily learn the Strategy Design Pattern with Java – a second visit

Post to Twitter

The Strategy design pattern allows you to select algorithms at runtime. The Strategy pattern is a behavioural pattern and sometimes you will see it used in things like validation, sorting or where a large switch statement has been replaced – just to name a few.

I’ve written previously on the strategy design pattern however, for today’s article I wanted to re-visit this often overlooked pattern and present it in another way.


Note: I’m using NetBeans 7.1 but this will work with any Java IDE or if you wish compiled from the command line.

In my example I want to be able to fetch a file. The way I go about fetching that file might vary. I might use HTTP, FTP or even cURL. I want to be able to decide this at runtime though so I need a way to go about building this.

Creating the Project

  1. Create a simple Java application called: StrategyDemo
  2. Add an Interface file called: FetchFile
  3. Add four class files called: FetchFileViaCurl, FetchFileViaHTTP, FetchFileViaFTP, FileFetchContext

In the interface file FetchFile.java add the following code:

package strategydemo;

public interface FetchFile {
    public String fetch(String fileName);
}

Here I define a simple method that can be implemented in a class file. Keep in mind for the sake of simplicity I’m returning a string but in actuality you could be returning an actual file.

Lets go ahead and implement three classes that will do the work of fetching the file in their own way.

FetchFileViaHTTP.java

package strategydemo;

public class FetchFileViaHTTP implements FetchFile {

    @Override
    public String fetch(String fileName) {
        return String.format("The file (%s) has been retrieved via HTTP", fileName);
    }

}

You can see above that the file would be fetched using HTTP.

FetchFileViaFTP.java

package strategydemo;

public class FetchFileViaFTP implements FetchFile {

    @Override
    public String fetch(String fileName) {
        return String.format("The file (%s) has been retrieved via FTP", fileName);
    }

}

FetchFileViaCurl.java

package strategydemo;

public class FetchFileViaCurl implements FetchFile {

    @Override
    public String fetch(String fileName) {
        return String.format("The file (%s) has been retrieved via cURL", fileName);
    }

}

I now have an interface and three implementation classes. Next, I’ll write a context class which can be used to pass the “strategy” they want to utilize.

FileFetchContext.java

package strategydemo;


public class FileFetchContext {
    private FetchFile strategyFetchFile;

    public FileFetchContext(FetchFile strategyFetchFile) {
        this.strategyFetchFile = strategyFetchFile;
    }

    public String fetch(String fileName) {
        return this.strategyFetchFile.fetch(fileName);
    }
}

The above class is pretty simple. You pass the “strategy” you want to use in the constructor (this could be done in a setter as well) and then call the fetch method with the file you want to retrieve.

Lets take a look at the StrategyDemo class (if you are using an IDE this file was probably already created – if not you will need to create it) to see how we can make this all work.

StrategyDemo.java

package strategydemo;

public class StrategyDemo {

    public static void main(String[] args) {
        FileFetchContext fetchFileContext = new FileFetchContext(
                new FetchFileViaHTTP());
        System.out.println(fetchFileContext.fetch("some.doc"));

        fetchFileContext = new FileFetchContext(
                new FetchFileViaCurl());
        System.out.println(fetchFileContext.fetch("any.doc"));

        fetchFileContext = new FileFetchContext(
                new FetchFileViaFTP());
        System.out.println(fetchFileContext.fetch("fancy.doc"));
    }
}

I create the context class and pass in the class I want it to use.

The output when run is as follows:

The file (some.doc) has been retrieved via HTTP
The file (any.doc) has been retrieved via cURL
The file (fancy.doc) has been retrieved via FTP

Post to Twitter

This entry was posted in Design Patterns, Java. Bookmark the permalink.