本篇文章給大家分享的內容是關於PHP策略模式,有著一定的參考價值,有需要的朋友可以參考一下
例如:一個電商網站系統,針對男性女性使用者要各自跳轉到不同的商品類目,並且所有廣告位展示不同的廣告
6 項目應用
6.1 需求說明
實現一個商場收銀系統,商品可以有正常收費,打折收費,返利收費等模式(來之《大話設計模式》)
6.2 需求分析
按照需求,可以將收費操作設計成為一個介面演算法,正常收費,打折收費,返利收費都繼承這個介面,實現不同的策略演算法。然後設計一個環境類,去維護策略的執行個體。
6.3 設計架構圖
6.4 程式源碼下載
http://download.csdn.net/detail/clevercode/8700009
6.5 程式說明
1)strategy.php
[php] view plain copy
<?php /** * strategy.php * * 策略類:定義了一系列的演算法,這些演算法都是完成的相同工作,但是實現不同。 * * 特別聲明:本原始碼是根據《大話設計模式》一書中的C#案例改成成PHP代碼,和書中的 * 代碼會有改變和最佳化。 * * Copyright (c) 2015 http://blog.csdn.net/CleverCode * * modification history: * -------------------- * 2015/5/5, by CleverCode, Create * */ // 定義介面現金策略,每種策略都是具體實現acceptCash,但都是實現收取現金功能 interface ICashStrategy{ // 收取現金 public function acceptCash($money); } // 正常收取策略 class NormalStrategy implements ICashStrategy{ /** * 返回正常金額 * * @param double $money 金額 * @return double 金額 */ public function acceptCash($money){ return $money; } } // 打折策略 class RebateStrategy implements ICashStrategy{ // 打折比例 private $_moneyRebate = 1; /** * 建構函式 * * @param double $rebate 比例 * @return void */ public function __construct($rebate){ $this->_moneyRebate = $rebate; } /** * 返回正常金額 * * @param double $money 金額 * @return double 金額 */ public function acceptCash($money){ return $this->_moneyRebate * $money; } } // 返利策略 class ReturnStrategy implements ICashStrategy{ // 返利條件 private $_moneyCondition = null; // 返利多少 private $_moneyReturn = null; /** * 建構函式 * * @param double $moneyCondition 返利條件 * @return double $moneyReturn 返利多少 * @return void */ public function __construct($moneyCondition, $moneyReturn){ $this->_moneyCondition = $moneyCondition; $this->_moneyReturn = $moneyReturn; } /** * 返回正常金額 * * @param double $money 金額 * @return double 金額 */ public function acceptCash($money){ if (!isset($this->_moneyCondition) || !isset($this->_moneyReturn) || $this->_moneyCondition == 0) { return $money; } return $money - floor($money / $this->_moneyCondition) * $this->_moneyReturn; } }
2) strategyPattern.php
[php] view plain copy
<?php /** * strategyPattern.php * * 設計模式:策略模式 * * 模式簡介: * 它定義了演算法家族,分別封裝起來,讓它們之間可以互相替換,此模式讓演算法的變化, * 不會影響到使用演算法的客戶。 * 策略模式是一種定義一些列演算法的方法,從概念上來看,所有這些演算法完成的都是 * 相同的工作,只是實現不同,它可以以相同的方式調用所有的演算法,減少了各種演算法類 * 與使用演算法類的耦合。 * 本源碼中的各種結賬方式,其實都是在結賬,但是具體的實現確實不同的。策略模式與 * 命令模式不同的是,命令模式的演算法是相互獨立的,每個命令做的工作是不同的。而策略模式 * 卻是在做通一種工作。 * * 特別聲明:本原始碼是根據《大話設計模式》一書中的C#案例改成成PHP代碼,和書中的 * 代碼會有改變和最佳化。 * * Copyright (c) 2015 http://blog.csdn.net/CleverCode * * modification history: * -------------------- * 2015/5/14, by CleverCode, Create * */ // 載入所有的策略 include_once ('strategy.php'); // 建立一個環境類,根據不同的需求調用不同策略 class CashContext{ // 策略 private $_strategy = null; /** * 建構函式 * * @param string $type 類型 * @return void */ public function __construct($type = null){ if (!isset($type)) { return; } $this->setCashStrategy($type); } /** * 設定策略(簡單工廠與策略模式混合使用) * * @param string $type 類型 * @return void */ public function setCashStrategy($type){ $cs = null; switch ($type) { // 正常策略 case 'normal' : $cs = new NormalStrategy(); break; // 打折策略 case 'rebate8' : $cs = new RebateStrategy(0.8); break; // 返利策略 case 'return300to100' : $cs = new ReturnStrategy(300, 100); break; } $this->_strategy = $cs; } /** * 擷取結果 * * @param double $money 金額 * @return double */ public function getResult($money){ return $this->_strategy->acceptCash($money); } /** * 擷取結果 * * @param string $type 類型 * @param int $num 數量 * @param double $price 單價 * @return double */ public function getResultAll($type, $num, $price){ $this->setCashStrategy($type); return $this->getResult($num * $price); } } /* * 用戶端類 * 讓用戶端和商務邏輯儘可能的分離,降低用戶端和商務邏輯演算法的耦合, * 使商務邏輯的演算法更具有可移植性 */ class Client{ public function main(){ $total = 0; $cashContext = new CashContext(); // 購買數量 $numA = 10; // 單價 $priceA = 100; // 策略模式擷取結果 $totalA = $cashContext->getResultAll('normal', $numA, $priceA); $this->display('A', 'normal', $numA, $priceA, $totalA); // 購買數量 $numB = 5; // 單價 $priceB = 100; // 打折策略擷取結果 $totalB = $cashContext->getResultAll('rebate8', $numB, $priceB); $this->display('B', 'rebate8', $numB, $priceB, $totalB); // 購買數量 $numC = 10; // 單價 $priceC = 100; // 返利策略擷取結果 $totalC = $cashContext->getResultAll('return300to100', $numC, $priceC); $this->display('C', 'return300to100', $numC, $priceC, $totalC); } /** * 列印 * * @param string $name 商品名 * @param string $type 類型 * @param int $num 數量 * @param double $price 單價 * @return double */ public function display($name, $type, $num, $price, $total){ echo date('Y-m-d H:i:s') . ",$name,[$type],num:$num,price:$price,total:$total\r\n"; } } /** * 程式入口 */ function start(){ $client = new Client(); $client->main(); } start(); ?>