The Framework as an Implementation Detail Marcello Duarte / Konstantin Kudryashov
May 10, 2015
The Framework as an Implementation DetailMarcello Duarte / Konstantin Kudryashov
@_md @everzeta SensioLabsEvent
About us
@_mdMarcello Duarte HEAD OF TRAINING, INVIQA
@everzetKonstantin Kudryashov BDD PRACTICE MANAGER, INVIQA
@_md @everzeta SensioLabsEvent
This talk
[ Convenience ][ Choices ][ Future ]
@_md @everzeta SensioLabsEvent
Choice
Convenience
http://www.flickr.com/photos/johnwinkelman/6200402992/
@_md @everzeta SensioLabsEvent
We dolove .
@_md @everzeta SensioLabsEvent
Promise
“A framework is ‘just’ one of the tools to help you develop better and faster”
– Symfony documentation
@_md @everzeta SensioLabsEvent
“The only way to go fast is to go well” – Uncle Bob
FAST SLOW
QUALITY SWITCH
@_md @everzeta SensioLabsEvent
Relative cost of repair
analysis design code test support
@_md @everzeta SensioLabsEvent
Convenientvs
Maintainable
@_md @everzeta SensioLabsEvent
A framework is “convenient” when it makes choices for you
BookController e
xtends Controlle
r
AuthorsController extends ContainerAwareController
@_md @everzeta SensioLabsEvent
The code is maintainable when the framework lets you make
the choices
@_md @everzeta SensioLabsEvent
Instability and abstractnessinstability
abstractness
@_md @everzeta SensioLabsEvent
The “convenient” code is usually not very testable
@_md @everzeta SensioLabsEvent
Symfony can be convenient
public function updateAction($id){ $em = $this->getDoctrine()->getManager(); $product = $em->getRepository('AcmeStoreBundle:Product')->find($id);
if (!$product) { throw $this->createNotFoundException( 'No product found for id '.$id ); }
$product->setName('New product name!'); $em->flush();
return $this->redirect($this->generateUrl('homepage'));}
@_md @everzeta SensioLabsEvent
The “convenient” Controllertends to ask for more
Integration Tests
@_md @everzeta SensioLabsEvent
Integration Testsstinks of coupling
@_md @everzeta SensioLabsEvent
Feedback
Outer QualityInner Quality
Acceptance TestsUnit Tests
@_md @everzeta SensioLabsEvent
Choice
Choices
http://www.flickr.com/photos/tmartin/32010732/
@_md @everzeta SensioLabsEvent
Should we always TDD? what the Start Up said what the Craftsmen said
@_md @everzeta SensioLabsEvent
We doTest Driven Design
@_md @everzeta SensioLabsEvent
Design is about choices
@_md @everzeta SensioLabsEvent
Design is a professional activity
@_md @everzeta SensioLabsEvent
TDD is about communication
@_md @everzeta SensioLabsEvent
TDD is about your stakeholders
@_md @everzeta SensioLabsEvent
The developers in the team are also stakeholders
@_md @everzeta SensioLabsEvent
TDD is for long term relationships
@_md @everzeta SensioLabsEvent
How many dependencies can you spot?
public function updateAction($id){ $em = $this->getDoctrine()->getManager(); $product = $em->getRepository('AcmeStoreBundle:Product')->find($id);
if (!$product) { throw $this->createNotFoundException( 'No product found for id '.$id ); }
$product->setName('New product name!'); $em->flush();
return $this->redirect($this->generateUrl('homepage'));}
@_md @everzeta SensioLabsEvent
How many dependencies can you spot?
public function updateAction($id){ $em = $this->getDoctrine()->getManager(); $product = $em->getRepository('AcmeStoreBundle:Product')->find($id);
if (!$product) { throw $this->createNotFoundException( 'No product found for id '.$id ); }
$product->setName('New product name!'); $em->flush();
return $this->redirect($this->generateUrl('homepage'));}
DoctrineRedirectRouterModel
@_md @everzeta SensioLabsEvent
Hexagonal Architecture
“The hexagon is not a hexagon because the number six is important, but rather to allow the people doing the drawing
to have room to insert ports and adapters as they need”
:)
[Cockburn 08]
@_md @everzeta SensioLabsEvent
http://www.flickr.com/photos/10849858@N00/2696404813
@_md @everzeta SensioLabsEvent
http://www.flickr.com/photos/mac_users_guide/3680586328/
@_md @everzeta SensioLabsEvent
your application
@_md @everzeta SensioLabsEvent
web gui app
your application
user side ports
test adapter
@_md @everzeta SensioLabsEvent
web gui app
your application
user side ports
test adapter
data side ports
db access service
in memory
db
@_md @everzeta SensioLabsEvent
Hexagonal Architecture
Dbrest
Logs
@_md @everzeta SensioLabsEvent
Dependency Inversion
Higher level modules should not depend on lower level details
[Martin 02]
@_md @everzeta SensioLabsEvent
Naive implementation
controller
use case
utility
uses
uses
@_md @everzeta SensioLabsEvent
Dependency Inversion
use case
serviceadapter
utilityadapter
service
utility
@_md @everzeta SensioLabsEvent
Choice
Let’s see some code
@_md @everzeta SensioLabsEvent
Choice
Future
@_md @everzeta SensioLabsEvent
Choice
Thanks!joind.in/9331
github.com/MarcelloDuarte/hexagonal-symfony