我可能會執行此錯誤,因爲我無法找出設置策略模式實施策略的可靠方法。我不是一個「靜態」編寫的粉絲,也許還有另一種方式。在策略模式中設置策略
背景故事:我爲了檢索任何用戶輸入前端跟蹤&跟蹤信息做了兩(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。 –