Last Updated:

Strategy pattern | PHP

The "Strategy" pattern is used in situations where a common problem needs to be solved with several different algorithms depending on the context.

The choice of solution can be based on the choice of the user. For example, graphics programs allow you to save images in different graphic formats, each of which has a unique code. However, the process for choosing each of the formats is the same.

This pattern can solve the problem of presenting a web application in different languages or styles. The simplest schemas can be derived from an array of translated words or an array of colors for a theme, but complex settings may require significant coding to achieve dynamic output. I ran into such a problem when I was making international versions of an e-commerce site.

In addition to language differences, different countries may have their own units of measurement or representation of the format of numbers. The feature may solve some problems, but it will not help with monetary units. Americans use the $ sign to the left of the amount. Europeans can use eur or the euro sign.number_format

To implement the "Strategy" pattern, you must develop a common interface for all algorithms. You can then make different implementations of this interface. In PHP, this can be implemented by creating a common class from which subclasses will be inherited. In this case, you can take advantage of polymorphism.

The following is the base class. It defines two methods and . The first method returns the currency format. The second method returns a translated phrase from English. A base class defines basic functionality that can be extended into subclasses.localizationformatMoneytranslate

<?php 

    //Strategy super class 
    class localization 
    { 
        function formatMoney($sum) 
        { 
            number_format($sum); 
        } 

        function translate($phrase) 
        { 
            return($phrase); 
        } 
    } 

?>

The following is the English subclass of the . This class takes care of putting the "-" sign to the left of the $ sign. The translate method is not repurposed because it is assumed that all phrases will be entered in English.localization

<?php 
    include_once('localization.php'); 
    class english extends localization 
    { 
        var $word; 

        function formatMoney($sum) 
        { 
            $text = ""; 
            //negative signs precede dollar signs 
            if($sum < 0) 
            { 
                $text .= "-"; 
                $sum = abs($sum); 
            } 
            $text .= "$" . number_format($sum, 2, '.', ','); 
            return($text); 
        } 
    } 
?>

Below is the German subclass of the class . This class uses intervals to separate thousands and commas to separate decimals. In addition, this subclass simply redefines the method , which handles only yes and no. In a real application, you need to use the database for this purpose.localizationtranslate

<?php 
    include_once('localization.php'); 
    class german extends localization 
    { 
        var $word; 
        function formatMoney($sum) 
        { 
            $text = "DM " . number_format($sum, 2, ',', '.'); 
            return($text); 
        } 
        function translate($phrase) 
        { 
            if($phrase == 'yes') 
            { 
                return('ja'); 
            } 
            if($phrase == 'no') 
            { 
                return('nein'); 
            } 
            return($phrase); 
        } 
    } 
?>

Finally, an example of the use of subclasses is given. The script can select a subclass based on user preferences or other sources, such as an HTTP header or domain name. In this implementation, subclasses are stored in files with the same names. Note that the variable .$language

<?php 
    //initialize 
    $language = 'english'; 
    include($language . '.php'); 
    $local = new $language; 
    //test formatting 
    print($local->formatMoney(12345678) . "<br>\n"); 
    print($local->translate('yes') . "<br>\n"); 
?>

One of the advantages of the "Strategy" pattern is the elimination of a bunch of comparisons. Imagine that one script contains all the functionality for formatting numbers for any language. It will definitely have a switch or a lot of if-else. In addition, you will need to process more code than is necessary for a particular page.

This pattern defines a user-friendly interface for expansion. You can start with just one localization module, and then you can easily attach any other language modules using native speakers. This can be applied not only for localization, in this way you can solve any problem that requires different algorithms depending on the context.