2013-08-27 56 views
1

在我的应用程序中,用户可以注册3种许可证:一种免费许可证,适用于所有人,一种人们必须付费的订阅许可证(通过外部方管理)许可发票,这需要他们与我们联系。以不同的方式处理不同的响应

人们可以在注册时或之后通过他们的个人资料选择他们的许可证。这是两种不同方法的控制器。

我有一个subscription.manager服务方法subscribe(User $user, License $license),它接收用户和许可证实体并处理签署用户正确许可证的所有逻辑。

基于什么授权选择的用户,结果可能有所不同:

  • 如果他们选择的自由,他们重定向到一个感谢您网页
  • 如果他们选择的发票,他们得到重定向到一些页确认他们已要求发票
  • 如果他们选择订阅,他们需要先重定向到付款页面。

最后一个选项是一个简单的RedirectResponse,但基于他们是否注册,或简单地改变他们现有的许可认购,我想显示不同的网页。

什么是最好的处理方法?

此刻,我这样做:

$response = $this->get('subscription.manager')->subscribe($user, $license); 

switch (true) { 
    case $response instanceof SuccessResponse: 
     return $this->redirect('success_url'); 
    break; 
    case $response instanceof RequestedResponse; 
     return $this->redirect('requested_url'); 
    break; 
    case $response instanceof RedirectResponse: 
     return $response; 
    break; 
    default: 
     throw new \Exception('Response not recognized'); 
} 

SuccessResponseRequestedResponse是简单的类我创建并保持几乎没有自己的信息,他们纯粹是表明该方法发生了什么事。

这允许我复制粘贴这个块,并简单地切换成功和请求的网址。但是,这感觉不是最佳的。有没有更好的方法来做到这一点?

我想我可以创建成功和请求的响应(无论是重定向还是渲染)并将其传递给服务方法。但是这感觉就像我违反了单一责任原则。

回答

1

我不认为你的订阅管理员应该关心重定向和东西。所以作为第一步我会这样做:

$result = $this->get('subscription.manager')->subscribe($user, $license); 

switch ($result) { 
    case 'ProcessedFreeLicense': 
     return $this->redirect('success_url'); 
    break; 
    case 'ProcessedInvoicedLicense'; 
     return $this->redirect('requested_url'); 
    break; 
    case 'ProcessedSubstrictionLicense': 
     return $response; 
    break; 
    default: 
     throw new \Exception('Response not recognized'); 
} 

这仍然留给你在控制器中的switch语句和一些重复的代码。您可以将switch语句移到基本控制器类。

但是,我会考虑派遣一个ProcessedLicense事件,然后让听众决定为每种许可证执行什么操作。看看FOSUserBundle.RegistrationController的开发版本,一个工作的例子,但基本上是:

​​

所以现在所有处理中的一个或多个听众可以,但夹着一张执照后做什么相关的逻辑的。它可以根据需要进行更改,而不会影响控制器。

============================================== =======================

只是想我会添加第三种方法的完整性。这种方法在一些基于C#/ Java的应用程序中很常见。这是一种“火警和遗忘”的方法,其中命令不会返回值,控制器也不会期望值。

// This is the Command. It does not return a value. 
$this->get('subscription.manager')->subscribe($user, $license); 

// Always just go here 
return $this->redirect('user_license_status_page'); 

显然我们简化了命令对象,因为它不再需要返回一个值。我们摆脱了共享开关语句。 licence_status控制器可以向用户显示发生的情况,并在必要时采取进一步的行动。

+0

事件监听器是一个好主意!另外,你可以阅读更多关于[事件组件](http://symfony.com/doc/current/components/event_dispatcher/introduction.html) – Touki

相关问题