Ross Tuck
21 november 2013
Ibuildings organiseert regelmatig een interne workshop. Hierbij worden (veelal) technische onderwerpen behandeld en aan de hand van een opdracht verder uitgewerkt.
Maar hoe maak je een workshop over Symfony 2 en Domain Driven Design (DDD) interessant voor iedereen?
Gewoon, door een memegenerator te bouwen.
Ook al lijkt een klein en minder technische uitdaging, er zijn bepaalde onderdelen die je bewust of onbewust toepast in het opzetten van een memegenerator. Hieronder volgen een paar voorbeelden.
Bundle indeling
Om overzicht te houden, is een duidelijke indeling van je bundles/packages een must.
Naamgeving
Net als bij opstellen van je entiteiten, functies en variabelen is naamgeving o zo belangrijk. Hetzelfde geldt voor je bundles.
Dus gebruik geen algemene naam als CoreBundle of MainBundle, maar een meer expliciete naam.
In de workshop hebben we bijvoorbeeld een MemeBundle en een Meme package. Waarbij in de Meme package alle business logica/entiteiten (DDD domain objecten) bevat en de MemeBundle zorgt voor de integratie met Symfony.
Integratie
Een best practice is dat je alle integratie met het Symfony framework in een afzonderlijke bundle opneemt
Voor de Memegenerator gebruiken we de ‘ImageGeneratorBundle’ als ‘integratie’ bundle voor het gebruik van de image generator class. Een ander goed voorbeeld is het authenticeren van gebruikers via Google oAuth.
Functionaliteit
Wanneer je een ’large-scale’ project opzet deel je deze op in kleinere sub-systemen om je project beheerbaar te houden. Door deze onderverdeling ook in je bundles door te voeren krijg je een veel duidelijker overzicht van je Symfony project.
Denk er ook aan dat de naamgeving overeenkomt met de terminologie binnen je applicatie (Ubiquitous Language) en de daadwerkelijke functionaliteit, bijvoorbeeld ‘NotificationMailerBundle’ ipv. ‘MailBundle’.
!
Value objects
Een van de krachtige concepten in DDD is het gebruik van value objecten. Een belangrijke eigenschap is dat value objecten nooit veranderen (immutable).
Een value object is ideaal om kleine functionaliteit en validatie op te nemen. Hierdoor zijn ze ook makkelijk te unit-testen. Daarbij verklein je de kans op fouten in je applicatie.
In de workshop gebruiken we de entiteit ‘Meme’ voor het genereren van de afbeelding. Een meme bestaat altijd uit een ’lead line’ and ‘punch line’. De titel ‘Workshops’ is de lead line en ‘Workshops everywhere’ is de punch line.
Je kan beide regels onderbrengen in 1 Caption value object.
namespace Ibuildings\MemeBundle\Value;
/** * Meme Caption Value Object */ class Caption { private $lead; private $punchLine;
/\*\*
\* Constructs a caption based on a lead and punch line.
\*/
public function \_\_construct($lead, $punchLine)
{
$this->lead = $lead;
$this->punchLine = $punchLine;
}
/\*\*
\* Lead of the Meme Caption
\*
\* @return string
\*/
public function getLead()
{
return $this->lead;
}
/\*\*
\* Punch line of the Meme Caption
\*
\* @return string
\*/
public function getPunchLine()
{
return $this->punchLine;
}
}
Een hoop andere objecten komen ook in aanmerking voor het gebruik als Value objecten.
Denk hierbij aan Money, DateTime en zelfs Address objecten.
Everywhere
Zo zie je maar: het maakt niet uit hoe klein of groot een workshop/project is ‘best practices’ pas je overal toe!
Wil je meer weten over deze onderwerpen kijk dan ook eens naar:
- Models and Service Layers by @rosstuck
- Value Objects and User Interfaces by @mathiasverraes
- DDD with Symfony 2 by @couac (William Durand)