Hola symfoneros, estoy trabajando en un proyecto en Symfony2 + Doctrine2 y los controllers se me están engordando ya demasiado con tareas que entiendo que pertenecen al modelo.
Había pensado que para aligerarlos podría empezar con extraer todo el código que pertenece al modelo en forma de servicios. Así si por ejemplo tengo un action del controller que (pongamos que estamos en Twitter) crea un tuit a partir de un formulario y notifica a todos los seguidores, la idea sería crear un servicio (e.g. twitter.tweets) con un método publish($tweet). El controller seguiría instanciando y trabajando con un objeto Tweet pero no tendría ningún $em->flush() ni nada por el estilo.
Las ventajas vendrían a ser estas:
- El controller hace sólo de pasarela entre el usuario y el modelo
- El modelo se puede reutilizar en otros contextos (en procesos batch, por ejemplo)
- Puedo cambiar la implementación del modelo sin afectar a los controllers (e.g. pasar de usar una base de datos a un web service)
Uno de los aspectos que me genera más dudas es la forma de encapsular correctamente los cambios sobre las entities. Doctrine por defecto recuerda los cambios que se hacen en las entidades y ahí pierdo la encapsulación que me da el servicio ya que al hacer un $em->flush() se aplicarían todos los cambios que se hayan podido hacer en cualquier entidad y sin mucho control sobre qué quiero aplicar y qué no en la base de datos.
Para evitar esto había pensado en algo así:
class TweetsService
{
function publish(Tweet $tweet)
{
$this->getEntityManager()->clear();
$this->getEntityManager()->merge($tweet);
$this->getEntityManager()->flush();
$this->notifyFollowers($tweet);
}
}
Básicamente olvida todos los cambios hechos en las entidades (el clear() hace un detach() de todas ellas) y aplica sólo los que nos interesan.
Cómo veis esta aproximación? Me estoy liando sólo? Va a afectar mucho en el rendimiento? Con las pruebas que he hecho hasta ahora la cosa funciona pero no me gustaría encontrarme con problemas más adelante.
Un saludo.