漫談設計模式之工廠模式
阿新 • • 發佈:2017-06-04
設計模式 策略模式 工廠模式 單例模式
今天在這裏不過多介紹什麽是設計模式和為什麽要使用它?可以參考漫談設計模式之組合模式。
一、什麽是抽象工廠設計模式?
一言以蔽之,抽象工廠就是用來創建功能相關的類,
二、在什麽場景下使用它?
顧名思義,在我們的業務當中會有一種場景,有一個查詢頁面,上面有很多很多的查詢條件,最終你會組合這些查詢條件查詢出實際想要的數據,請問你是怎麽做的?下面是我的設計,運用了單例、工廠和策略模式,一切面向接口編程。
三、設計思路
1、定義策略接口,定義一個format方法
2、按實際業務抽象出三種策略,1、模糊查詢,2、等於查詢,3、要經過特殊處理的查詢
3、定義一個抽象工廠,按需初始化三種策略對象
4、定義一個統一入口TutorConditionFormatter,創建工廠對象,工廠對象創建策略對象,策略對象處理數據,最後返回要求格式
5、業務當中直接調用TutorConditionFormatter
<?php //------策略模式 /** * 策略模式interface * TutorConditionFormatterInterface */ namespace Logic\Tutor\ConditionFactoryFormatter; interface TutorConditionFormatterInterface { public function format($aTutor); } <?php /** * 模糊查詢策略 * TutorConditionLikeFormatter */ namespace Logic\Tutor\ConditionFactoryFormatter; class TutorConditionLikeFormatter implements TutorConditionFormatterInterface { public function format ($aParams) { $aFormatColumn = [‘certifications‘,‘background‘,‘interview_time‘]; $aParamKey = array_keys($aParams); $aFormatKey = array_intersect($aFormatColumn,$aParamKey); $aCondition = []; if ($aFormatKey) { foreach ($aFormatKey as $column) { $item = $aParams["$column"]; if (!empty($item)) { $item = array_unique($item); sort($item); $aCondition[] = sprintf("%s like ‘%s‘",$column,‘%‘.implode(",", $item).‘%‘); } } } return $aCondition; } } <?php /** * 特殊查詢策略 * TutorConditionSpecialFormatter */ namespace Logic\Tutor\ConditionFactoryFormatter; class TutorConditionSpecialFormatter implements TutorConditionFormatterInterface { const HAVE_RESUME = 1;//已上傳簡歷 const NONE_RESUME = 2;//未上傳簡歷 public function format ($aParams) { $aCondition = []; if (isset($aParams[‘nationality‘]) && !empty($aParams[‘nationality‘])) { //對於others,查詢非United States和Canada的集合 if ($aParams[‘nationality‘] > 2) { $aCondition[] = sprintf(‘nationality >=3‘); } else { $aCondition[] = sprintf("nationality = %d",$aParams[‘nationality‘]); } } if (isset($aParams[‘resume‘]) && !empty($aParams[‘resume‘])) { if (self::HAVE_RESUME == $aParams[‘resume‘]) { $aCondition[] = sprintf("resume <> ‘‘"); } elseif (self::NONE_RESUME == $aParams[‘resume‘]) { $aCondition[] = sprintf("resume = ‘‘"); } } if (isset($aParams[‘sourcing_team‘]) && !empty($aParams[‘sourcing_team‘])) { if (is_array($aParams[‘sourcing_team‘])) { $aCondition[] = sprintf("sourcing_team in(‘%s‘)",implode("‘,‘", $aParams[‘sourcing_team‘])); } else { $aCondition[] = sprintf("sourcing_team = %s",$aParams[‘sourcing_team‘]); } } if (isset($aParams[‘demo_time_start‘]) && !empty($aParams[‘demo_time_start‘])) { $aCondition[] = sprintf("demo_result_date >= ‘%s 00:00:00‘",$aParams[‘demo_time_start‘]); } if (isset($aParams[‘demo_time_end‘]) && !empty($aParams[‘demo_time_end‘])) { $aCondition[] = sprintf("demo_result_date <= ‘%s 23:59:59‘",$aParams[‘demo_time_end‘]); } return $aCondition; } } <?php /** * 相等查詢策略 * TutorConditionEqualFormatter */ namespace Logic\Tutor\ConditionFactoryFormatter; class TutorConditionEqualFormatter implements TutorConditionFormatterInterface { const STATUS_FAILED = ‘failed‘; public function format ($aParams) { $aFormatColumn = [‘mobile‘,‘country‘,‘state‘,‘email‘,‘time_zone‘,‘teaching_experience‘,‘zoom_id‘, ‘interviewer‘,‘demo_status‘,‘sa_signed‘,‘skype_id‘,‘self_applied‘,‘source‘,‘educational_attainment‘ ]; $aParamKey = array_keys($aParams); $aFormatKey = array_intersect($aFormatColumn,$aParamKey); $aCondition = []; if ($aFormatKey) { foreach ($aFormatKey as $column) { $item = $aParams["$column"]; if (!empty($item)) { $aCondition[] = sprintf("%s = ‘%s‘",$column,$item); } } } return $aCondition; } } //------抽象工廠 <?php /** * 查詢條件格式化工廠 * TutorConditionFactory */ namespace Logic\Tutor\ConditionFactoryFormatter; class TutorConditionFactory { private $_oFactory = null; public static $_instance = null; /** * TutorConditionFactory constructor. */ private function __construct () { if($this->_oFactory == null) { $this->register(); } } /** * @return TutorConditionFactory|null */ public static function getInstance() { if (self::$_instance == null) { self::$_instance = new TutorConditionFactory(); } return self::$_instance; } /** * 註冊工廠類 * @return $this */ public function register() { $this->_oFactory[‘equal‘] = __NAMESPACE__ . ‘\TutorConditionEqualFormatter‘; $this->_oFactory[‘like‘] = __NAMESPACE__ . ‘\TutorConditionLikeFormatter‘; $this->_oFactory[‘special‘] = __NAMESPACE__ . ‘\TutorConditionSpecialFormatter‘; return $this; } /** * 創建工廠類 * @param $type * @return mixed * @throws \Exception */ public function create($type) { if (!array_key_exists($type,$this->_oFactory)) { throw new \Exception(sprintf("%s is not valid",$type)); } $producer = $this->_oFactory["$type"]; return new $producer(); } } <?php /** * 格式化數據統一入口,完成兩件事 * 按要求生產策略對象 * 按策略對象格式化處理數據,最終返回所需的數據格式 */ namespace Logic\Tutor; use \Logic\Tutor\ConditionFactoryFormatter; class TutorConditionFormatter { public function __construct () { //定義需要處理的策略 $this->_aFormatter = [‘equal‘,‘like‘,‘special‘]; } public function format($aParams) { $oFactory = ConditionFactoryFormatter\TutorConditionFactory::getInstance(); //刪除p和psize,與tutor無關 unset($aParams[‘p‘],$aParams[‘psize‘]); $aCondition[] = sprintf("training_type_id >=1"); if (empty($aParams)) { return $aCondition; } //根據要求的策略處理數據,返回要求的數據 foreach ($this->_aFormatter as $formatter) { $oProducer = $oFactory->create($formatter); $item = $oProducer->format($aParams); $aCondition = array_merge($aCondition,$item); } unset($formatter,$item,$aParams); return array_unique($aCondition); } } //業務當中具體使用 <?php //工廠模式格式化查詢條件 $oConditionFormatter = new TutorConditionFormatter(); /** * $aSearch 是接受的請求參數 * $aCondition 是最終處理好的可供DbModel直接使用的查詢條件數據 */ $aCondition = $oConditionFormatter->format($aSearch);
本文出自 “我相信” 博客,請務必保留此出處http://mrcelite.blog.51cto.com/2977858/1932030
漫談設計模式之工廠模式