Permalink
Browse files

Moved doctrine knowledge into a manager class

The controller didn't need to know about the implementation
details of doctrine, it only needs to know that our application
can provide some blog posts objects. Therefore we introduce
a "Manager" class whose job it is to do that.
  • Loading branch information...
peterjmit committed Sep 4, 2013
1 parent 55c0bf8 commit 4a87e1d447c106e479b335a0a95c81d4feddfefa
@@ -5,25 +5,18 @@
use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
-use Doctrine\Common\Persistence\ManagerRegistry;
-use Doctrine\Common\Persistence\ObjectManager;
-use Doctrine\Common\Persistence\ObjectRepository;
+use Peterjmit\BlogBundle\Model\BlogManagerInterface;
use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface;
use Symfony\Component\HttpFoundation\Response;
class BlogControllerSpec extends ObjectBehavior
{
function let(
- ManagerRegistry $registry,
- ObjectManager $manager,
- ObjectRepository $repository,
+ BlogManagerInterface $manager,
EngineInterface $templating
) {
- $registry->getManager()->willReturn($manager);
- $manager->getRepository('PeterjmitBlogBundle:Blog')->willReturn($repository);
-
- $this->beConstructedWith($registry, $templating);
+ $this->beConstructedWith($manager, $templating);
}
function it_is_initializable()
@@ -32,11 +25,11 @@ function it_is_initializable()
}
function it_should_respond_to_index_action(
- ObjectRepository $repository,
+ BlogManagerInterface $manager,
EngineInterface $templating,
Response $mockResponse
) {
- $repository->findAll()->willReturn(array());
+ $manager->findAll()->willReturn(array());
$templating
->renderResponse(
@@ -2,24 +2,23 @@
namespace Peterjmit\BlogBundle\Controller;
-use Doctrine\Common\Persistence\ManagerRegistry;
+use Peterjmit\BlogBundle\Model\BlogManagerInterface;
use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface;
class BlogController
{
- private $doctrine;
+ private $manager;
private $templating;
- public function __construct(ManagerRegistry $doctrine, EngineInterface $templating)
+ public function __construct(BlogManagerInterface $manager, EngineInterface $templating)
{
- $this->doctrine = $doctrine;
+ $this->manager = $manager;
$this->templating = $templating;
}
public function indexAction()
{
- $entityManager = $this->doctrine->getManager();
- $posts = $entityManager->getRepository('PeterjmitBlogBundle:Blog')->findAll();
+ $posts = $this->manager->findAll();
return $this->templating->renderResponse('PeterjmitBlogBundle:Blog:index.html.twig', array(
'posts' => $posts
@@ -28,8 +27,7 @@ public function indexAction()
public function showAction($id)
{
- $entityManager = $this->doctrine->getManager();
- $post = $entityManager->getRepository('PeterjmitBlogBundle:Blog')->find($id);
+ $post = $this->manager->find($id);
if (!$post) {
throw $this->createNotFoundException(sprintf('Blog post %s was not found', $id));
@@ -0,0 +1,9 @@
+<?php
+
+namespace Peterjmit\BlogBundle\Model;
+
+interface BlogManagerInterface
+{
+ function findAll();
+ function find($id);
+}

12 comments on commit 4a87e1d

@docteurklein

This comment has been minimized.

Show comment
Hide comment
@docteurklein

docteurklein Sep 5, 2013

That's very good stuff! Great that you put that into words, in a clear and concrete example!

However, I would have implemented the interface in this commit, so that you can have a working controller at the end :)

I know that following DDD would make you create a semantic interface, but https://github.com/doctrine/common/blob/master/lib/Doctrine/Common/Persistence/ObjectRepository.php is already a good fit.

What about making the repository a service ?

That's very good stuff! Great that you put that into words, in a clear and concrete example!

However, I would have implemented the interface in this commit, so that you can have a working controller at the end :)

I know that following DDD would make you create a semantic interface, but https://github.com/doctrine/common/blob/master/lib/Doctrine/Common/Persistence/ObjectRepository.php is already a good fit.

What about making the repository a service ?

@everzet

This comment has been minimized.

Show comment
Hide comment
@everzet

everzet Sep 5, 2013

Even more specifically - use concrete BlogRepository.

Even more specifically - use concrete BlogRepository.

@docteurklein

This comment has been minimized.

Show comment
Hide comment

right.

@peterjmit

This comment has been minimized.

Show comment
Hide comment
@peterjmit

peterjmit Sep 5, 2013

Owner

I think you chaps are right, the example would be simpler/would benefit from just injecting the repository rather than BlogManagerInterface.

Its more habit rather than anything because I've always found the way FOSUserBundle had managers for the entities with the repository injected useful.

Owner

peterjmit replied Sep 5, 2013

I think you chaps are right, the example would be simpler/would benefit from just injecting the repository rather than BlogManagerInterface.

Its more habit rather than anything because I've always found the way FOSUserBundle had managers for the entities with the repository injected useful.

@everzet

This comment has been minimized.

Show comment
Hide comment
@everzet

everzet Sep 5, 2013

@peterjmit just don't forget that interfaces though are cleanest, are not the only way to define public communication protocol. Classes public API forms communication protocols as well. And yes, interfaces are the purest form of protocol. Question actually is do you need this purest protocol in that particular case ;)

@peterjmit just don't forget that interfaces though are cleanest, are not the only way to define public communication protocol. Classes public API forms communication protocols as well. And yes, interfaces are the purest form of protocol. Question actually is do you need this purest protocol in that particular case ;)

@silviuvoicu

This comment has been minimized.

Show comment
Hide comment
@silviuvoicu

silviuvoicu Sep 5, 2013

@peterjmit how to inject BlogManagerInterface in the constructor of BlogController, for the templating is easy, because is already a service with an id.

@peterjmit how to inject BlogManagerInterface in the constructor of BlogController, for the templating is easy, because is already a service with an id.

@peterjmit

This comment has been minimized.

Show comment
Hide comment
@peterjmit

peterjmit Sep 5, 2013

Owner

@silviuvoicu I'll do a follow up with some concrete code, but you would need to both write a concrete implementation of BlogManager define it as a service, define your controller as a service then pass the manager service as an argument

Owner

peterjmit replied Sep 5, 2013

@silviuvoicu I'll do a follow up with some concrete code, but you would need to both write a concrete implementation of BlogManager define it as a service, define your controller as a service then pass the manager service as an argument

@silviuvoicu

This comment has been minimized.

Show comment
Hide comment
@cordoval

This comment has been minimized.

Show comment
Hide comment
@cordoval

cordoval Sep 5, 2013

I guess when you say "Classes public API " you talking about adjusting rather the uniquitous language (DDD related) so changing the method names on our models, that is defining a domain language I guess ...? or what exactly if i am totally lost 👶 ?

I guess when you say "Classes public API " you talking about adjusting rather the uniquitous language (DDD related) so changing the method names on our models, that is defining a domain language I guess ...? or what exactly if i am totally lost 👶 ?

@docteurklein

This comment has been minimized.

Show comment
Hide comment
@docteurklein

docteurklein Sep 5, 2013

No, he means the public methods defined for a class. They are, by definition, accessible, and "open to receive messages". Otherwise, they would be protected.

No, he means the public methods defined for a class. They are, by definition, accessible, and "open to receive messages". Otherwise, they would be protected.

@cordoval

This comment has been minimized.

Show comment
Hide comment
@cordoval

cordoval Sep 5, 2013

thanks for the prescription Dr. 👶

thanks for the prescription Dr. 👶

Please sign in to comment.