使用策略设计模式排序

时间:2018-03-21 00:21:04

标签: php

我无法理解如何使用策略模式进行排序。我需要按字母顺序或数字顺序对表进行排序,具体取决于要排序的数据。我有代码

以下是已添加排序功能的表格的代码(不是策略模式)。

    <?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;
?>

我的第一个问题是,如果策略模式排序将使用相同的方法,则使用op = 1,2,3或4.或者如果完全取出以使用策略模式。

1 个答案:

答案 0 :(得分:2)

策略模式背后的想法是你编写实现接口的单独类,然后在主处理类或函数中,一旦有用户输入,就可以根据需要创建相应类的对象。

在您的分拣示例中,没有强有力的论据可以说策略模式非常适合这种情况,因为通常特定类的实现细节会有很大差异。

一个常见的例子是电子商务应用程序的不同支付处理器实现,它们之间可能存在广泛的差异。

对于一个数据阵列的简单分类,你已经证明可以用几乎完全相同的代码完成每种情况,这对于策略模式来说并不是一个很好的地方,但我猜这是一项学术练习。

从界面开始:

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

然后为实现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;
   }
}

在为每个分类创建类的时候,使用类的对象创建替换每个案例的代码,然后使用该对象调用$ obj-&gt; sort();而不是if-then-elsif链,使用switch()

可以更清晰
switch ($_GET['op']) {
    case 1:
        $sorter = new SortByName();
        break;
    case 2:
        $sorter = new SortById();
        break;

    // Other cases
}

$product = $sorter->sort($product);