CHAPTER 4 – Strategy Pattern
4.4.1 Strategy Pattern The strategy pattern is typically used when your programmer's algorithm should be interchangeable with different variations of the algorithm. For example, if you have code that creates an image, under certain circumstances, you might want to create JPEGs and under other circumstances, you might want to create GIF files. The strategy pattern is usually implemented by declaring an abstract base class with an algorithm method, which is then implemented by inheriting concrete classes. At some point in the code, it is decided what concrete strategy is relevant; it would then be instantiated and used wherever relevant. Our example shows how a download server can use a different file selec- tion strategy according to the web client accessing it. When creating the HTML with the download links, it will create download links to either .tar.gz files or .zip files according to the browser's OS identification. Of course, this means that files need to be available in both formats on the server. For sim- plicity's sake, assume that if the word "Win" exists in $_SERVER["HTTP_ USER_AGENT"], we are dealing with a Windows system and want to create .zip links; otherwise, we are dealing with systems that prefer .tar.gz. In this example, we would have two strategies: the .tar.gz strategy and the .zip strategy, which is reflected as the following strategy hierarchy (see Figure 4.3). abstract class FileNamingStrategy abstract createLinkName() class class ZipFileNamingStrategy TarGzFileNamingStrategy createLinkName() createLinkName() Fig. 4.3 Strategy hierarchy.
The following code snippet should give you an idea of how to use such a strategy pattern: abstract class FileNamingStrategy { abstract function createLinkName($filename); } class ZipFileNamingStrategy extends FileNamingStrategy { function createLinkName($filename) { return "http://downloads.foo.bar/$filename.zip"; } } class TarGzFileNamingStrategy extends FileNamingStrategy { function createLinkName($filename) { return "http://downloads.foo.bar/$filename.tar.gz"; } } if (strstr($_SERVER["HTTP_USER_AGENT"], "Win")) { $fileNamingObj = new ZipFileNamingStrategy(); } else { $fileNamingObj = new TarGzFileNamingStrategy(); } $calc_filename = $fileNamingObj->createLinkName("Calc101"); $stat_filename = $fileNamingObj->createLinkName("Stat2000"); print <<<EOF <h1>The following is a list of great downloads<</h1> <br> <a href="$calc_filename">A great calculator</a><br> <a href="$stat_filename">The best statistics application</a><br> <br> EOF; Accessing this script from a Windows system gives you the following HTML output: <h1>The following is a list of great downloads<</h1> <br> <a href="http://downloads.foo.bar/Calc101.zip">A great calculator< a><br> <a href="http://downloads.foo.bar/Stat2000.zip">The best statistics application</a><br> <br> Tip: The strategy pattern is often used with the factory pattern, which is described later in this section. The factory pattern selects the correct strategy.