Hexagonal symfony

Download Hexagonal symfony

Post on 08-Sep-2014




3 download

Embed Size (px)


What would your application look like if it were written by the people who write the testing frameworks? If unit tests make classes more modular, by forcing you to test it in isolation, then what is the effect of expanding this to a less granular level, the acceptance and functional test. The more modern application architecture evolves, the more we hear the very old patterns being rediscovered and re-adopted. 1979 Trygve's MVC is a classic example, so are the SOLID principles. In this talk we will look on how Symfony allows for a really decoupled, easy to test application, by following on the footsteps of Alistair Cockburn's hexagonal architecture.


  • Hexagonal Symfony MarcelloDuarte @_md SensioLabs
  • @_md SensioLabs Aboutme MarcelloDuarte SensioLabs UK @_md work contribute tweet
  • @_md SensioLabs Whydowecareabout maintainability?
  • @_md SensioLabs ConveniencevsMaintainability
  • @_md SensioLabs Maintainabilityisnota thingforthefuture
  • @_md SensioLabs Wecannotmanagewhatwecannot measure
  • @_md SensioLabs Wecannotmanagewhatwecannot measure
  • @_md SensioLabs Wecannotmanagewhatwecannot change
  • @_md SensioLabs A framework isjustone of the tools to help you develop better and faster Symfony documentation
  • @_md SensioLabs Faster is not enough
  • @_md SensioLabs Growable http://upload.wikimedia.org/wikipedia/commons/3/39/Domestic_Goose.jpg
  • @_md SensioLabs Key in making great and growable systems is to design how its modules communicate [and not] what their properties and behaviours should be. ViewpointsResearchInstituteSource-BonnieMacbirdURL-http://www.vpri.org
  • @_md SensioLabs real procedure Sum (k, l, u, ak) value l, u; integer k, l, u; real ak; begin real S; S := 0; for k := l step 1 until u do S := S + ak; Sum := S; end; x := Sum( i, 1, n, V[i] );
  • @_md SensioLabs FromBlockStructuretoOO
  • @_md SensioLabs Glyph Class Char (c); Character c; Begin Procedure print; OutChar(c); End;
  • @_md SensioLabs Module A Module B flowofcontrol? sourcecodedependency?
  • @_md SensioLabs controller use case utility uses uses Nave Implementation
  • @_md SensioLabs ! 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 SensioLabs ! public { $em $product ! ! $product $em ! } Doctrine Redirect Model Router
  • @_md SensioLabs Module A Polymorphic Dependency Inversion Principle Module B [Martin 02]
  • @_md SensioLabs use case service adapter utility adapter service utility
  • @_md SensioLabs Layered Architecture User Interface Application Domain Infrastructure [Evans 04]
  • @_md SensioLabs
  • @_md SensioLabs 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 SensioLabs http://www.ickr.com/photos/10849858@N00/2696404813 world
  • @_md SensioLabs http://www.ickr.com/photos/mac_users_guide/3680586328/
  • @_md SensioLabs HexagonalArchitecture your application
  • @_md SensioLabs web gui app your application usersideports test adapter
  • @_md SensioLabs web gui app your application usersideports test adapter datasideports db access in memory db
  • @_md SensioLabs Db rest Logs
  • @_md SensioLabs Architectureisaboutintent [Martin 02]
  • @_md SensioLabs Dreamthefeature
  • @_md SensioLabs
  • @_md SensioLabs Dreamtheboundaries
  • @_md SensioLabs L&D app ! ! Learning Domain Google Auth Employees API Twitter bootstrap
  • @_md SensioLabs Expressintent
  • @_md SensioLabs < Domain < Application < Delivery Port < Persistency Port
  • @_md SensioLabs Contextalsohaveboundaries
  • @_md SensioLabs
  • @_md SensioLabs Controllersdependonusecases
  • @_md SensioLabs /** * @Route(service="controllers.skills") */ class SkillsController { private $competencyFinder; private $raterFinder; ! public function __construct(CompetencyFinder $competencyFinder) { $this->competencyFinder = $competencyFinder; } ! /** * @Route("/skills", name="skills") * @Template() * Show the skill for the learners role */ public function indexAction() { return ['competencies' => $this->competencyFinder->findDictionary()]; } }
  • @_md SensioLabs Usecasesdependonthedomain servicesandports
  • @_md SensioLabs