今天在这里不过多介绍什么是设计模式和为什么要使用它?可以参考漫谈设计模式之组合模式。
一、什么是抽象工厂设计模式?
一言以蔽之,抽象工厂就是用来创建功能相关的类,
二、在什么场景下使用它?
顾名思义,在我们的业务当中会有一种场景,有一个查询页面,上面有很多很多的查询条件,最终你会组合这些查询条件查询出实际想要的数据,请问你是怎么做的?下面是我的设计,运用了单例、工厂和策略模式,一切面向接口编程。
三、设计思路
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
原文地址:http://mrcelite.blog.51cto.com/2977858/1932030