Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where to place business logic in Symfony2?

Tags:

After reading a lot of posts and Stack Overflow resources, I've still got some problems about the famous question about "where to put business logic?" Reading StackOverflow Question and A Blog Post, I believe I've understood the issue of code separation well.

Suppose I have a web form where you can add a user that will be added to a db. This example involves these concepts:

  • Form
  • Controller
  • Entity
  • Service
  • Repository

If I didn't miss something, you have to create an entity with some properties, getters, setters and so on in order to make it persist into a db. If you want to fetch or write that entity, you'll use entityManager and, for "non-canonical" query, entityRepository (that is where you can fit your "query language" query).

Now you have to define a service (that is a PHP class with a "lazy" instance) for all business logic; this is the place to put "heavy" code. Once you've recorded the service into your application, you can use it almost everywhere and that involves code reuse and so on.

When you render and post a form, you bind it with your entity (and with constraints of course) and use all the concepts defined above to put all together.

So, "old-me" would write a controller's action in this way:

public function indexAction(Request $request)     {         $modified = False;         if($request->getMethod() == 'POST'){ // submit, so have to modify data             $em = $this->getDoctrine()->getEntityManager();             $parameters = $request->request->get('User'); //form retriving             $id = $parameters['id'];             $user = $em->getRepository('SestanteUserBundle:User')->find($id);             $form = $this->createForm(new UserType(), $user);             $form->bindRequest($request);             $em->flush();             $modified = True;         }          $users = $this->getDoctrine()->getEntityManager()->getRepository('SestanteUserBundle:User')->findAll();         return $this->render('SestanteUserBundle:Default:index.html.twig',array('users'=>$users));     } 

"New-me" has refactored code in this way:

   public function indexAction(Request $request)     {         $um = $this->get('user_manager');         $modified = False;         if($request->getMethod() == 'POST'){ // submit, so have to modify data             $user = $um->getUserById($request,False);             $form = $this->createForm(new UserType(), $user);             $form->bindRequest($request);             $um->flushAll();             $modified = True;          }         $users = $um->showAllUser();         return $this->render('SestanteUserBundle:Default:index.html.twig',array('users'=>$users));     } 

Where $um is a custom service where all code that you can't see from #1 code piece to #2 code piece is stored.

So, here are my questions:

  1. Did I, finally, get the essence of symfony2 and {M}VC in general?
  2. Is the refactor a good one? If not, what would be a better way?

Post Scriptum: I know that I can use the FOSUserBundle for User store and authentication, but this is a basic example for teach myself how to work with Symfony. Moreover, my service was injected with ORM.Doctrine.* in order to work (just a note for who read this question with my same confusion)

like image 538
DonCallisto Avatar asked Jul 17 '12 13:07

DonCallisto


People also ask

Where do you put your business logic typically?

Business logic should live in the data model. And, what's more, it should live in the graph data model because that's the right abstraction for the next twenty years. If you've been paying attention to this blog or to Stardog generally, then you must have known this is where we were going to end up.

CAN controller contain business logic?

Let me tell you this, controllers shouldn't do anything remotely related to business logic, and directly access data stores. The controller's only purpose is to receive a request and return a response. Everything that goes in between is not its responsibility.


1 Answers

There are two main approaches regarding on where to put the business logic: the SOA architecture and the domain-driven architecture. If your business objects (entities) are anemic, I mean, if they don’t have business logic, just getters and setters, then you will prefer SOA. However, if you build the business logic inside your business objects, then you will prefer the other. Adam Bien discusses these approaches:

Domain-driven design with Java EE 6: http://www.javaworld.com/javaworld/jw-05-2009/jw-05-domain-driven-design.html

Lean service architectures with Java EE 6: http://www.javaworld.com/javaworld/jw-04-2009/jw-04-lean-soa-with-javaee6.html

It’s Java, but you can get the idea.

like image 186
André Avatar answered Sep 22 '22 21:09

André