漫谈设计模式之工厂模式
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了漫谈设计模式之工厂模式相关的知识,希望对你有一定的参考价值。
今天在这里不过多介绍什么是设计模式和为什么要使用它?可以参考漫谈设计模式之组合模式。
一、什么是抽象工厂设计模式?
一言以蔽之,抽象工厂就是用来创建功能相关的类,
二、在什么场景下使用它?
顾名思义,在我们的业务当中会有一种场景,有一个查询页面,上面有很多很多的查询条件,最终你会组合这些查询条件查询出实际想要的数据,请问你是怎么做的?下面是我的设计,运用了单例、工厂和策略模式,一切面向接口编程。
三、设计思路
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
以上是关于漫谈设计模式之工厂模式的主要内容,如果未能解决你的问题,请参考以下文章