Dopo aver letto un sacco di post e risorse Stack Overflow, ho ancora qualche problema con la famosa domanda su "dove mettere la logica aziendale?" Leggendo StackOverflow Question e A Blog Post, credo di aver capito bene il problema della separazione del codice.Dove posizionare la logica aziendale in Symfony2?
Supponiamo di disporre di un modulo Web in cui è possibile aggiungere un utente che verrà aggiunto a un db. Questo esempio riguarda questi concetti:
- Forma
- controller
- Entity
- Servizio
- Repository
Se non mi manca qualcosa, è necessario creare un soggetto con alcune proprietà, getter, setter e così via per renderlo persistente in un db. Se desideri recuperare o scrivere quell'entità, utilizzerai lo entityManager
e, per la query "non canonica", entityRepository
(è qui che puoi inserire la query "lingua di query").
Ora è necessario definire un servizio (ovvero una classe PHP con un'istanza "lazy") per tutte le logiche di business; questo è il posto dove mettere il codice "pesante". Una volta registrato il servizio nella tua applicazione, puoi usarlo quasi ovunque e ciò comporta il riutilizzo del codice e così via.
Quando si esegue il rendering e il post di un modulo, lo si lega con la propria entità (e con i vincoli ovviamente) e si utilizzano tutti i concetti sopra definiti per mettere tutti insieme.
Quindi, "vecchio-me" scriverei l'azione di un controller in questo modo:
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" ha refactoring del codice in questo modo:
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));
}
Dove $um
è un servizio personalizzato in cui è memorizzato tutto il codice che non è possibile vedere dal pezzo di codice n. 1 al pezzo di codice n.
Così, qui sono le mie domande:
- ho fatto, infine, ottenere l'essenza di Symfony2 e {M} VC in generale?
- Il refactoring è buono? In caso contrario, quale sarebbe un modo migliore?
Post Scriptum: So che posso usare il FOSUserBundle per il deposito e l'autenticazione utente, ma questo è un esempio di base per insegnare a me stesso come lavorare con Symfony. Inoltre, il mio servizio è stato iniettato con ORM.Doctrine. * Per funzionare (solo una nota per chi ha letto questa domanda con la mia stessa confusione)
Qual è lo scopo di $ modificato e qual è lo scopo del secondo parametro a getUserById ()? – redbirdo
Bene, la logica di business del dominio va in [model layer] (http://stackoverflow.com/a/5864000/727208). Mosley negli [oggetti dominio] (http://c2.com/cgi/wiki?DomainObject). –
@redbirdo: non ha importanza ai fini della domanda. – DonCallisto