今天在这里不过多介绍什么是设计模式和为什么要使用它?可以参考漫谈设计模式之组合模式。

一、什么是抽象工厂设计模式?

    一言以蔽之,抽象工厂就是用来创建功能相关的类,

二、在什么场景下使用它?

    顾名思义,在我们的业务当中会有一种场景,有一个查询页面,上面有很多很多的查询条件,最终你会组合这些查询条件查询出实际想要的数据,请问你是怎么做的?下面是我的设计,运用了单例、工厂和策略模式,一切面向接口编程。

三、设计思路

1、定义策略接口,定义一个format方法

2、按实际业务抽象出三种策略,1、模糊查询,2、等于查询,3、要经过特殊处理的查询

3、定义一个抽象工厂,按需初始化三种策略对象

4、定义一个统一入口TutorConditionFormatter,创建工厂对象,工厂对象创建策略对象,策略对象处理数据,最后返回要求格式

5、业务当中直接调用TutorConditionFormatter


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


_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();
    }
}


_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);
    }
}


//业务当中具体使用
format($aSearch);