我正在尝试确定用于全文搜索服务的最佳设计模式。我想象的基本逻辑如下所示,也有要点:https://gist.github.com/qutwala/1b574a39286a7525c8c7 当我调用search()方法时,它应该通过配置决定哪个搜索引擎(Sphinx,Solr等)以及该引擎要加载的实现(Local,API。)。
我不确定使用什么样的设计模式。起初,我认为可能涉及 Factory , Singleton 设计模式。
根据我目前的实施情况,我发现以下问题:
正如我之前提到的,我对使用模式的正确方式感兴趣,所以欢迎任何想法评论。
代码:
<?php
Interface SearchEngine
{
public function getSearchProperties();
public function setSearchProperties(SearchProperties $properties);
public function getImplementation($implementation);
}
Interface SearchPropertiesInterface
{
public function setIndex($index);
}
class SearchProperties implements SearchPropertiesInterface
{
private $properties = array();
public function setProperty($property, $value) {
echo "Set property <br />";
$this->properties[$property] = $value;
}
public function setIndex($index) {
$this->setProperty('index', $index);
}
}
class SphinxSearchEngine implements SearchEngine
{
private $SearchProperties;
public function __construct()
{
$this->SearchProperties = new SearchProperties();
}
private $implementations = array();
/**
* @param $implementation
*
* @return SphinxSearchImplementation
*/
public function getImplementation($implementation)
{
echo "Returned SphinxSearchEngineAPIImplementation <br />";
// TODO: on demand load a.ka. singleton?
$this->implementations[$implementation] = new SphinxSearchEngineAPIImplementation();
return $this->implementations[$implementation];
}
/**
* TODO: how to inject properties?
* TODO: what if changed implementation, should be injected in both?
*
* @return SearchProperties
*/
public function getSearchProperties()
{
return $this->SearchProperties;
}
public function setSearchProperties(SearchProperties $properties)
{
}
}
Interface SphinxSearchImplementation
{
public function search($query, $limit, $offset);
}
class SphinxSearchEngineAPIImplementation implements SphinxSearchImplementation
{
public function search($query, $limit, $offset) {
//TODO: how to get properties, index?
echo "Find results by SphinxSearchEngineAPIImplementation <br />";
}
}
class ElasticSearchEngine implements SearchEngine
{
private $implementations = array();
public function __construct()
{
$this->SearchProperties = new SearchProperties();
}
/**
* @param $implementation
*
* @return SphinxSearchImplementation
*/
public function getImplementation($implementation)
{
return $this->implementations[$implementation];
}
public function getSearchProperties()
{
return $this->SearchProperties;
}
public function setSearchProperties(SearchProperties $properties)
{
// TODO: how to inject properties?
// TODO: what if changed implementation, should be injected in both?
}
}
class Search
{
public function __construct() {
// magic goes here :)
}
private $config = array(
"engine" => "Sphinx|ElasticSearch"
);
public function getEngine()
{
echo "Loaded engine: Sphinx <br />";
return new SphinxSearchEngine(); // For example by config loaded sphinx SE?
}
public function search($query, $limit, $offset) {
// TODO: how to decide which engine to use?
// TODO: engine should have own properties set?
$this->getEngine()->getSearchProperties()->setIndex('search_index');
try {
$this->getEngine()->getImplementation('local|api')->search($query, $limit, $offset);
} catch (Exception $e) {
// TODO: What to do now, fallback to another engine?
}
}
}
$search = new Search();
$search->search('my search query', 10, 0);
答案 0 :(得分:0)
我认为,策略模式正是您所寻找的
因此,您将拥有工厂类,您可以在任何标志之间切换
如下所示:
class Factory()
{
public Factory CreateFactory(Enum parameter)
{
Factory manager = null;
switch(parameter)
{
case 1:
manager = new ImplementationOne();
break;
case 2:
manager new ImplementationTwo();
break;
else:
break;
}
return manager;
}
}
然后,您可以像往常一样拥有ImplementationOne类等。
参考: Strategy Pattern
谢谢,