我可能会执行此错误,因为我无法找出设置策略模式实施策略的可靠方法。我不是一个“静态”编写的粉丝,也许还有另一种方式。在策略模式中设置策略
背景故事:我为了检索任何用户输入前端跟踪&跟踪信息做了两(2)实现(SOAP + HTTP)航运商。他们每个人都遵循一个接口,以便我知道哪些功能是和应该(PHP:3)可用。我已经缩短了下面的类名,因为这是Magento,类名非常长。
流程:客户在窗体中输入跟踪编号并提交。请求被发送到控制器,控制器初始化一个Service类的实例,通过设置输出。 $ service-> setOutput('tracking/service_gls') - 注意tracking/service_gls直接映射到服务类(Magento的东西),$ service-> getDeliveryInformation($ number)被调用(我们知道这存在是因为接口),整个$ service对象返回到视图并显示数据。
我的挑战:我使用开关盒来设置跟踪/ service_gls和跟踪/ service_otherservice,然后调用getDeliveryInformation()。这是正确的方法吗?我觉得如果有人想连接另一家航运供应商,这有点太静态,很难维持。他们将不得不进入控制器并手动添加另一个条目到开关盒中,在该类中的某个200线以下的功能中。
的控制器的外观示例:
public function getDeliveryInformationAction()
{
$id = $this->getRequest()->getParam('id', false);
if ($id && $this->getRequest()->isAjax())
{
// SO note: service parameter is just two radio buttons with values "gls", "otherservice"
$serviceType = $this->getRequest()->getParam('service', false);
try
{
// SO note: same as doing new Class()
$service = Mage::getModel('tracking/service');
switch ($serviceType)
{
case 'gls':
$service->setOutput('tracking/service_gls');
break;
case 'other':
$service->setOutput('tracking/service_other');
break;
}
$shipment = $service->getDeliveryInformation($id);
$output = // .. create block that contains the view, $output will contain the shipment data; this is returned to the ajax request.
}
catch (Exception_RequestError $e)
{
..
}
// finally
$this->getResponse()->setHeader('content-type', 'text/html', true);
$this->getResponse()->setBody($output);
}
}
代码已经缩短了一下,因为有很多更多的功能,但并不重要。
接口两个航运提供商模型实施
interface Output
{
/* Requests delivery information for the specified tracking number */
public function getDeliveryInformation($number);
/**
* Returns acceptor name
* @return string
*/
public function getAcceptorName();
}
服务类处理从运输模型
class Service
{
protected $output;
/**
* Sets the output model to use
* @param string $outputType
*/
public function setOutput($outputModel)
{
// SO note: same as doing new Class()
// Magento people note: getModel() works fine tho.. ;-)
$modelInstance = Mage::app()->getConfig()->getModelInstance($outputModel);
$this->output = $modelInstance;
}
/**
* Returns delivery information for the specified tracking number
* @param string $number
* @return instance of output class
*/
public function getDeliveryInformation($number)
{
// SO note: This makes the shipping class request
// information and set data internally on the object
$this->output->getDeliveryInformation($number);
return $this->output;
}
}
实施例的船类的请求数据;我有两个在这种情况下
class Service_Gls implements Output
{
const SERVICE_NAME = 'GLS';
const SERVICE_URL = 'http://www.gls-group.eu/276-I-PORTAL-WEBSERVICE/services/Tracking/wsdl/Tracking.wsdl';
protected $locale = 'da_DK';
/* Class constructor */
public function __construct() { }
/**
* Requests delivery information for the specified tracking number
* @param mixed $number
*/
public function getDeliveryInformation($number)
{
$this->_getDeliveryInformation($number);
}
/**
* Requests and sets information for the specified tracking number
* @param mixed $number
*/
private function _getDeliveryInformation($number)
{
// SO note: Extending from Varien_Object has magic __get, __set .. hence why there is no getData() function in this class.
if (!count($this->getData()))
{
$client = new SoapClient($url);
$client->GetTuDetail($reference));
.. set data
}
}
/**
* Returns acceptor name
* @return string
*/
public function getAcceptorName()
{
$signature = $this->getSignature();
return (isset($signature)) ? $this->getSignature() : false;
}
/**
* Returns the name of the current service
* @return string
*/
public function __toString()
{
return self::SERVICE_NAME;
}
}
控制器
class AjaxController extends Mage_Core_Controller_Front_Action
{
public function getDeliveryInformationAction()
{
$id = $this->getRequest()->getParam('id', false);
if ($id && $this->getRequest()->isAjax())
{
// SO note: service parameter is just two radio buttons with values "gls", "otherservice"
$serviceType = $this->getRequest()->getParam('service', false);
try
{
$service = Mage::getModel('tracking/service');
switch ($serviceType)
{
case 'gls':
$service->setOutput('tracking/service_gls');
break;
case 'other':
$service->setOutput('tracking/service_other');
break;
}
$shipment = $service->getDeliveryInformation($id);
$output = // .. create block that contains the view, $output will contain the shipment data; this is returned to the ajax request.
}
catch (Exception_RequestError $e)
{
..
}
// finally
$this->getResponse()->setHeader('content-type', 'text/html', true);
$this->getResponse()->setBody($output);
}
}
}
感谢您的意见。我跟你常在一起。所以基本上你会建议我添加一个包含我的类和其他逻辑的上下文,以返回正确的类,然后将其返回给调用getDeliveryInformation()的Service类?我仍然需要在我的Controller类中进行某种switch/if /然后调用Context tho;这似乎是一种“浪费”,因为我可以在我的Service类中执行逻辑?也许我是误解。创建Service类是为了使逻辑不在我的Controller中。 – Michael
Wel我假设你正在使用服务容器:顺便提一下框架?无论如何,在控制器,你需要拨打的是 –
对不起,这是星期天morninh在这里和东西侵入。无论如何,我已经延长了我的答案。我会在一分钟或20分钟内添加服务mofds。 –