i'm trying clean older symfony2 project of code inside controllers. long, repetitive blocks of code in controller not optimal, makes debugging & development tedious , error-prone.
there plenty of things can clean , move services, blocks of code provide sort of reusable functionality. well-defined task should live in service, , controllers should "wiring".
but no matter move code, there small repetitive blocks cluttering up. things initialization/transformation/parsing/filtering patterns example, used extensively in our application.
take example data "kneading" needed creation of datatable:
class defaultcontroller extends controller { public function indexaction() { $data = array(/* 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 common, verbose pattern. our developers tend store dozens of these kinds of little patterns in text files on own computers, , copy/paste them controllers.
if try think of solutions make code bit more concise (and dry), there multiple options.
- i filter duplicate patterns out of actions , dump them private functions. i've done in locations clear things bit, it's bad solution localized each controller.
- i create 1 or more generalized "helper" classes these code snippets, ,
use
them whenever need them in service or controller, containing kinds of parsing/checking/filtering/building functions. turn garbage collection of tiny unrelated methods though. - i create 1 or more abstract classes properties/methods used in many services/controllers, , inherit that. feels hacky, if need sandwich in between user defined controller , symfony framework controller class.
- i define traits these data-transformation functions, , use wherever applicable. people claim php traits bad. however, traits seem least abusive , concise option me.
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(/* data */); $datatable = $this->buildtable($this->get('datatables.orders'),$data); return array('datatable'=>$datatable); } }
that reduces 6 lines of boilerplate 1.
are traits bad solution this? if so, options better?
you might @ moving things services. example:
$serializer = $this->get('json.getset.serializer');
and maybe make data table factory service
$datatable = $this->get('datatable.orders.factory')->create($data);
you go 1 step further, define controllers services inject needed dependencies. end with:
$datatable = $this->datatablefactory->create($data);
Comments
Post a Comment