服务似乎与所描述的用途非常相符。
最近,我研究了一个会计解决方案。我使用了很多复杂的算法,很快我就有了很长的方法,甚至尝试优化代码。
服务很容易调用,它们的使用可以使控制器更性感、更轻便,并通过使用与特定操作相对应的独立服务使大方法更易读、更可切割。
并且它们可以在其他组件中使用,只要存在 DependencyInjection,如果您可能需要在控制器的另一个上下文中应用它,它就足以移动您的逻辑。
声明很简单:
services:
acmeapp.calculation:
class: Acme\AppBundle\Services\CalculationService
arguments: ["@doctrine.orm.entity_manager", "@acmeapp.anotherservice"]
还有服务
class CalculationService {
protected $em;
protected $another;
public function __constructor(EntityManager $entityManager, AnotherService $anotherService)
{
$this->em = $entityManager;
$this->another = $anotherService;
}
//...
}
Controller-Service 方法主要是一种服务,具有其所有优点。
您的服务的方法可以呈现视图并使用 _controller 属性关联路由,如下所示:
display_data_a:
path: /data/A
methods: GET
defaults: { _controller: acmeapp.calculation:dealWithData }
无需从Symfony\Bundle\FrameworkBundle\Controller\Controller 扩展您的服务,但是,当然,您可以使用它。
此外,如果您的控制器之间有许多重复的代码和几个不同的字符,那么抽象 BaseController 可能是一个非常干净的替代方案。
这是我在使用服务之前所做的,如果方法与我对控制器的定义相对应,这与@fabpot 在您的链接中所说的相对应。
DIC 主要帮助管理“全局”对象。控制器不是全局对象。此外,控制器应尽可能薄。它主要是您的模型和视图/模板之间的粘合剂。因此,如果您需要能够自定义,这可能意味着您需要重构它们并从中提取业务逻辑。
更多关于 OOP 中的 BaseController,
方法很简单,如果你有一行代码在一个方法中重复了两三次,你就使用一个变量。
对于代码块也是如此,您将使用一种方法。
对于控制器来说也是一样的,如果你有两个或多个相同类型的对象(这里是一个控制器),你应该使用 AbstractController(或 BaseController),在其中移动你重复的方法(当然只有一次),然后删除它们从子控制器。
基础控制器:
class BaseController extends Controller
{
/**
* Shortcut for get doctrine entity manager.
*/
public function getEntityManager()
{
return $this->getDoctrine->getEntityManager();
}
/**
* Shortcut for locate a resource in the application.
*/
public function locateResource($path)
{
return $this->get('kernel')->locateResource($path);
}
// ...
}
并将其用作子控制器的一部分
class ChildController extends BaseController
{
public function helloAction()
{
$em = $this->getEntityManager();
$file = $this->locateResource('@AcmeAppBundle/Resources/config/hello.yml');
// ...
}
}
希望这可以帮助您避免大量重复代码。