Sorting with Strategy Design Pattern

99
March 21, 2018, at 11:31 AM

I am having trouble trying to understand how to sort using Strategy Pattern. I need to sort a table alphabetically or numerically depending on the data being sorted. I have code

Here is code of the table with sorting feature already added (not Strategy Pattern).

    <?php
  $product = array(
   array('name' => 'Carrot', 'id' => 'V_001', 'cat' => 'Vegetable', 'price' => '0.59'),
   array('name' => 'Potato', 'id' => 'V_002', 'cat' => 'Vegetable', 'price' => '0.69'),
   array('name' => 'Onion', 'id' => 'V_003', 'cat' => 'Vegetable', 'price' => '0.45'),
   array('name' => 'Beet', 'id' => 'V_004', 'cat' => 'Vegetable', 'price' => '0.39'),
   array('name' => 'Radish', 'id' => 'V_005', 'cat' => 'Vegetable', 'price' => '0.14'),
   array('name' => 'Apple', 'id' => 'F_001', 'cat' => 'Fruit', 'price' => '1.19'),
   array('name' => 'Pear', 'id' => 'F_002', 'cat' => 'Fruit', 'price' => '0.89'),
   array('name' => 'Orange', 'id' => 'F_003', 'cat' => 'Fruit', 'price' => '1.05'),
   array('name' => 'Bananna', 'id' => 'F_004', 'cat' => 'Fruit', 'price' => '0.59'),
   array('name' => 'Peach', 'id' => 'F_0015', 'cat' => 'Fruit', 'price' => '1.33'),
   array('name' => 'Oats', 'id' => 'G_001', 'cat' => 'Grain', 'price' => '0.49'),
   array('name' => 'Rice', 'id' => 'G_002', 'cat' => 'Grain', 'price' => '0.74'),
   array('name' => 'Quinoa', 'id' => 'G_003', 'cat' => 'Grain', 'price' => '0.89'));
  if (isset($_GET['op'])) {
    if ($_GET['op'] == 1) {
        function sort_name($i, $j){
            $a = $i['name'];
            $b = $j['name'];
        if ($a == $b){
           return 0;
       }
       return ($a < $b) ? -1 : 1;
   }
uasort($product, "sort_name");
   } elseif ($_GET['op'] == 2) {
        function sort_id($i, $j){
            $a = $i['id'];
            $b = $j['id'];
        if ($a == $b){
            return 0;
       }
        return ($a < $b) ? -1 : 1;
        }
uasort($product, "sort_id");
   } elseif ($_GET['op'] == 3) {
        function sort_category($i, $j){
            $a = $i['cat'];
            $b = $j['cat'];
        if ($a == $b){
            return 0;
       }
        return ($a < $b) ? -1 : 1;
        }
uasort($product, "sort_category");
   } elseif ($_GET['op'] == 4) {
        function sort_price($i, $j){
            $a = $i['price'];
            $b = $j['price'];
        if ($a == $b){
            return 0;
       }
        return ($a < $b) ? -1 : 1;
        }
uasort($product, "sort_price");
   } else {
        function sort_name($i, $j){
            $a = $i['name'];
            $b = $j['name'];
        if ($a == $b){
           return 0;
       }
       return ($a < $b) ? -1 : 1;
   }
uasort($product, "sort_name");
   } 
  }
$myHeader = <<<HERE
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 <title>Products</title>
</head>
<body id="main_body" >
 <h2><a>Product Table</a></h2>
  <table>
   <tr>
    <td><a href="./hw2.php?op=1">Name</a></td>
    <td><a href="./hw2.php?op=2">Id</a></td>
    <td><a href="./hw2.php?op=3">Category</a></td>
    <td><a href="./hw2.php?op=4">Price</a></td>
    </tr>
HERE;
echo $myHeader;
foreach ($product as $item) {
 echo "<tr>";
 echo "<td>".$item['name']."</td>";
 echo "<td>".$item['id']."</td>";
 echo "<td>".$item['cat']."</td>";
 echo "<td>".$item['price']."</td>";
 echo "</tr>";
} 
$myBody= <<<EOB
  </table>
  </body>
</html>
EOB;
echo $myBody;
?>

My first question would be, If the strategy pattern sorting would use the same method, using the op = 1, 2, 3, or 4. Or if that is taken out completely to use the strategy pattern.

Answer 1

The idea behind the Strategy Pattern is that you write separate classes that implement an interface, and then in the main processing class or function you create an object of the appropriate class as required once you have user input.

In your sortation example, there's not a strong argument to be made that the Strategy Pattern is a good fit for this, as usually the implementation details of the specific classes are significantly different.

A common example would be different payment processor implementations for an e-commerce application, where there would likely be extensive differences between them.

For a simple sortation of an array of data which you've proven can be done with essentially almost the exact same code in each case, this isn't a great place for the Strategy pattern, but I am guessing this is an Academic exercise.

Start with an interface:

interface SortStrategyInterface {
    public function sort(Array $product);
}

Then create a class for each sortation that implements sortStrategy

class SortByName implements SortStrategyInterface {
    protected function sortName($i, $j){
        $a = $i['name'];
        $b = $j['name'];
        if ($a == $b){
            return 0;
        }
       return ($a < $b) ? -1 : 1;
    }
    public function sort($product) {
       uasort($product, array($this, 'sortName'));
       return $product;
   }
}

At the point you have created classes for each sortation, you replace the code for each case with the creation of an object of the class, and then use that object to call $obj->sort(); Rather than an if-then-elsif chain, this is much cleaner with a switch()

switch ($_GET['op']) {
    case 1:
        $sorter = new SortByName();
        break;
    case 2:
        $sorter = new SortById();
        break;
    // Other cases
}
$product = $sorter->sort($product);
READ ALSO
Move Woocommerce Product Image Gallery to Side of Featured Image

Move Woocommerce Product Image Gallery to Side of Featured Image

I'm customizing a WordPress theme with WooCommerce installedThe client would like the image gallery on the single product page moved from beneath the main image to beside it (under the product summary)

44
Adding Watermark to AWS Elastic Transcoder

Adding Watermark to AWS Elastic Transcoder

No matter where I place my overlaypng file (in the root of the bucket or in the folder of the input/output) the Watermark is not being applied using the following code:

69
file_get_contents(): SSL operation fails 1 with phpmyadmin

file_get_contents(): SSL operation fails 1 with phpmyadmin

I just run into a problem, in my html file I give my customer the option to choose his location either from map or my typing his address and my goal is to get his longitude and latitude in both occasionsUp until now when I tried both versions worked but now the typing...

99
PHP usort Multi-dimensional array

PHP usort Multi-dimensional array

I'm having trouble getting usort to work and not sure what I'm missingBelow is an example of my array

100