Reputation: 2566
I'm trying to clean up an older Symfony2 project where most of the code is inside controllers. Long, repetitive blocks of code in a controller is not optimal, it makes debugging & development very tedious and error-prone.
There are plenty of things I can easily clean up and move into services, as those blocks of code provide some sort of reusable functionality. I get that any well-defined task should live in a service, and controllers should just be "wiring".
But no matter where I move the code, there are always small repetitive blocks cluttering everything up. Things like initialization/transformation/parsing/filtering patterns for example, which are used extensively in our application.
Take for example the data "kneading" needed for the creation of a 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);
}
}
That's a very common, but also very verbose pattern. Our developers tend to store dozens of these kinds of little patterns in text files on their own computers, and often copy/paste them into controllers.
If I try to think of solutions to make the code a bit more concise (and DRY), there are multiple options.
use
them whenever I need them in a service or controller, containing all kinds of parsing/checking/filtering/building functions. It would probably turn into a garbage collection of tiny unrelated methods though.Consider this:
Bundle/Traits/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'));
}
}
Bundle/Controller/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);
}
}
That reduces 6 lines of boilerplate to 1.
Are traits a bad solution for this? If so, which options would be better?
Upvotes: 1
Views: 933
Reputation: 48865
You might look at moving some things into services. For example:
$serializer = $this->get('json.getset.serializer');
And maybe make a data table factory service
$dataTable = $this->get('datatable.orders.factory')->create($data);
You could even go one step further, define your controllers as services then inject the needed dependencies. So you would end up with:
$dataTable = $this->dataTableFactory->create($data);
Upvotes: 1