经过一段时间不知道如何正确地做到这一点,并避免在几个控制器中复制代码,我搜索并再次寻找,但找不到明确的答案。
特别是一个案例,需要计算一个实体完成的几个统计数据。该计算将用于3个不同的控制器。 在其中两个中,我将分解为不同的布局,第三个,我将使用此数据进行全局计算。 每次计算的业务逻辑涉及100多行代码,我不得不在不同的控制器中使用三倍。
计划可能是:
使用这3个值,我稍后进行总计算。
我能找到的选项是:
知道如何解决这种情况吗?
非常感谢
答案 0 :(得分:3)
服务似乎与描述的用法非常相符。
最近,我参与了会计解决方案。我使用了很多复杂的算法,很快就有很长的方法,甚至尝试优化代码。
服务很容易调用,它们的使用可以使控制器更加性感,更轻,并且通过使用与特定操作相对应的独立服务,使大方法可读并且更易于删除。
它们可以在其他组件中使用,只要存在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),移动你的重复方法(当然只有一次) ,并从子控制器中删除它们。
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');
// ...
}
}
希望这可以帮助您避免大量重复的代码。