用于消除Symfony2

时间:2015-09-25 22:35:45

标签: php symfony traits

我正在尝试清理旧的Symfony2项目,其中大部分代码都在控制器内部。控制器中长而重复的代码块并不是最佳的,它使得调试和调试成为可能。发展非常乏味且容易出错。

有很多东西我可以轻松清理并转移到服务中,因为这些代码块提供了某种可重用的功能。我知道任何明确定义的任务都应该存在于服务中,而控制器应该只是"布线"。

但是无论我在哪里移动代码,都会有一些小的重复块让一切都变得混乱。像初始化/转换/解析/过滤模式之类的东西,在我们的应用程序中广泛使用。

以数据为例"揉捏"创建DataTable所需的:

class DefaultController extends Controller {

    public function indexAction() {

        $data = array(/* some data */);

        $encoders = array(new JsonEncoder());
        $normalizers = array(new GetSetMethodNormalizer());
        $serializer = new Serializer($normalizers, $encoders);
        $datatable = $this->get('datatables.orders');
        $datatable->buildDatatableView();
        $datatable->setData($serializer->serialize($data, 'json'));

        return array('datatable'=>$datatable);
    }
}

这是一种非常普遍但也非常冗长的模式。我们的开发人员倾向于在自己的计算机上将几十种这样的小图案存储在文本文件中,并经常将它们复制/粘贴到控制器中。

如果我试着想出解决方案以使代码更简洁(和DRY),那么有多种选择。

  • 我可以从所有操作中过滤出重复的模式,并将它们转储到私有函数中。我已经在某些地方完成了这项工作,以便稍微清理一下,但这是一个本地化到每个控制器的糟糕解决方案。
  • 我可以创建一个或多个通用"帮助"包含所有这些代码片段的类,以及在服务或控制器中需要它们时use,包含各种解析/检查/过滤/构建函数。它可能会变成一个微小的无关方法的垃圾收集。
  • 我可以使用许多服务/控制器中使用的属性/方法创建一个或多个抽象类,并从中继承。感觉很讨厌,特别是如果我需要将它夹在用户定义的控制器和Symfony框架控制器类之间。
  • 我可以为这些数据转换函数定义特征,并在适用的地方使用它们。人们经常声称PHP特性几乎总是很糟糕。然而,对我而言,特征似乎是最不具有侮辱性和最简洁的选择。

考虑一下:

捆绑/性状/ TableTrait.php

Trait TableTrait {
    function serialize($data, $format){
        $encoders = array(new JsonEncoder());
        $normalizers = array(new GetSetMethodNormalizer());
        $serializer = new Serializer($normalizers, $encoders);
        return $serializer->serialize($data, $format);
    }

    function buildTable($table, $data){
        $datatable = $table;
        $datatable->buildDatatableView();
        $datatable->setData($this->serialize($data, 'json'));
    }
}

捆绑/控制器/ SomeController.php

class DefaultController extends Controller {

    use \Bundle\Traits\TableTrait;

    public function indexAction() {

        $data = array(/* some data */);
        $datatable = $this->buildTable($this->get('datatables.orders'),$data);

        return array('datatable'=>$datatable);
    }
}

将6行样板减少为1。

特质是否是一个糟糕的解决方案? 如果是这样,哪个选项会更好?

1 个答案:

答案 0 :(得分:1)

您可能会考虑将某些内容转移到服务中。例如:

$serializer = $this->get('json.getset.serializer');

也许制作数据表工厂服务

$dataTable = $this->get('datatable.orders.factory')->create($data);

您甚至可以更进一步,将控制器定义为服务,然后注入所需的依赖项。所以你最终会得到:

$dataTable = $this->dataTableFactory->create($data);