Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

of

PHP7 e Rich Domain Model Slide 1 PHP7 e Rich Domain Model Slide 2 PHP7 e Rich Domain Model Slide 3 PHP7 e Rich Domain Model Slide 4 PHP7 e Rich Domain Model Slide 5 PHP7 e Rich Domain Model Slide 6 PHP7 e Rich Domain Model Slide 7 PHP7 e Rich Domain Model Slide 8 PHP7 e Rich Domain Model Slide 9 PHP7 e Rich Domain Model Slide 10 PHP7 e Rich Domain Model Slide 11 PHP7 e Rich Domain Model Slide 12 PHP7 e Rich Domain Model Slide 13 PHP7 e Rich Domain Model Slide 14 PHP7 e Rich Domain Model Slide 15 PHP7 e Rich Domain Model Slide 16 PHP7 e Rich Domain Model Slide 17 PHP7 e Rich Domain Model Slide 18 PHP7 e Rich Domain Model Slide 19 PHP7 e Rich Domain Model Slide 20 PHP7 e Rich Domain Model Slide 21 PHP7 e Rich Domain Model Slide 22 PHP7 e Rich Domain Model Slide 23 PHP7 e Rich Domain Model Slide 24 PHP7 e Rich Domain Model Slide 25 PHP7 e Rich Domain Model Slide 26 PHP7 e Rich Domain Model Slide 27 PHP7 e Rich Domain Model Slide 28 PHP7 e Rich Domain Model Slide 29 PHP7 e Rich Domain Model Slide 30 PHP7 e Rich Domain Model Slide 31 PHP7 e Rich Domain Model Slide 32 PHP7 e Rich Domain Model Slide 33 PHP7 e Rich Domain Model Slide 34 PHP7 e Rich Domain Model Slide 35 PHP7 e Rich Domain Model Slide 36 PHP7 e Rich Domain Model Slide 37 PHP7 e Rich Domain Model Slide 38 PHP7 e Rich Domain Model Slide 39 PHP7 e Rich Domain Model Slide 40 PHP7 e Rich Domain Model Slide 41 PHP7 e Rich Domain Model Slide 42 PHP7 e Rich Domain Model Slide 43
Upcoming SlideShare
E-commerce con SF: dal case study alla realtà
Next
Download to read offline and view in fullscreen.

5 Likes

Share

Download to read offline

PHP7 e Rich Domain Model

Download to read offline

SymfonyDay 2016

Related Books

Free with a 30 day trial from Scribd

See all

PHP7 e Rich Domain Model

  1. 1. PHP7 e Rich Domain Model Massimiliano Arione - @garakkio SymfonyDay 2016
  2. 2. about
  3. 3. PHP 7 e Rich Domain Model
  4. 4. PHP 7 e Rich Domain Model Come sono arrivato a Rich Domain Model passando per PHP 7
  5. 5. Non parleremo di... ● quanto è figo PHP 7
  6. 6. Non parleremo di... ● quanto è figo PHP 7 ● teoria del Rich Domain Model, pattern e anti-pattern, ecc.
  7. 7. Non parleremo di... ● quanto è figo PHP 7 ● teoria del Rich Domain Model, pattern e anti-pattern, ecc.
  8. 8. C’era una volta Una classica applicazione Symfony...
  9. 9. Entità class Giocatore { private $squadra; private $nome; private $numeroDiMaglia; }
  10. 10. Mapping class Giocatore { /* @ORMManyToOne(targetEntity=”Squadra”) */ private $squadra; /* @ORMColumn() */ private $nome; /* @ORMColumn(type=”smallint”) */ private $numeroDiMaglia; }
  11. 11. Validazione class Giocatore { /* @ORMManyToOne(targetEntity=”Squadra”) @AssertNotNull() */ private $squadra; /* @ORMColumn() @AssertNotBlank() */ private $nome; /* @ORMColumn(type=”smallint”) @AssertNotNull() @AssertType(type=”integer”) @AssertRange(min=0,max=99 */ private $numeroDiMaglia; }
  12. 12. Form class GiocatoreType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('squadra') ->add('nome') ->add('numeroDiMaglia', IntegerType::class) ; } public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ 'data_class' => Giocatore::class, ]); } }
  13. 13. Setters class Giocatore { public function setSquadra(Squadra $squadra) { $this->squadra = $squadra; } public function setNome($nome) { $this->nome = $nome; } public function setNumeroDiMaglia($numero) { $this->numeroDiMaglia = $numero; } // ... }
  14. 14. Getters class Giocatore { // ... public function getSquadra() { return $this->squadra; } public function getNome() { return $this->nome; } public function getNumeroDiMaglia() { return $this->numeroDiMaglia; } }
  15. 15. Here comes PHP 7...
  16. 16. Here comes PHP 7... <=>
  17. 17. Here comes PHP 7... ● scalar type hints ● return types
  18. 18. Setters (tipizzati) class Giocatore { public function setSquadra(Squadra $squadra) { $this->squadra = $squadra; } public function setNome(string $nome) { $this->nome = $nome; } public function setNumeroDiMaglia(int $numero) { $this->numeroDiMaglia = $numero; } // ... }
  19. 19. Getters (tipizzati) class Giocatore { // ... public function getSquadra(): Squadra { return $this->squadra; } public function getNome(): string { return $this->nome; } public function getNumeroDiMaglia(): int { return $this->numeroDiMaglia; } }
  20. 20. Oops! Fatal error: Uncaught TypeError: Argument 1 passed to setNome() must be an instance of string, null given
  21. 21. Oops2 ! Fatal error: Uncaught TypeError: Argument 1 passed to setNome() must be an instance of string, null given Fatal error: Uncaught TypeError: Return value of getNome() must be an instance of string, null returned
  22. 22. Il vero problema Form squadra nome numeroDimaglia Entity squadra nome numeroDimaglia
  23. 23. Il vero problema Form squadra nome numeroDimaglia Entity squadra nome numeroDimaglia table squadra nome numero_di_maglia
  24. 24. DTO class GiocatoreDTO { public $squadra; public $nome; public $numeroDiMaglia; }
  25. 25. Form class GiocatoreType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('squadra') ->add('nome') ->add('numeroDiMaglia', IntegerType::class) ; } public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ 'data_class' => GiocatoreDTO::class, ]); } }
  26. 26. Action public function nuovoAction(Request $request) { $giocatore = new Giocatore(); $form = $this->createForm(GiocatoreType::class, $giocatore); if ($form->handleRequest($request)->isValid()) { $this->getDoctrine()->getManager()->persist($giocatore); $this->getDoctrine()->getManager()->flush(); return $this->redirectToRoute('giocatori'); } return $this->render('giocatore/nuovo.html.twig', [ 'form' => $form->createView(), ]); }
  27. 27. Action public function nuovoAction(Request $request) { $dto = new GiocatoreDTO(); $form = $this->createForm(GiocatoreType::class, $dto); if ($form->handleRequest($request)->isValid()) { $giocatore = new Giocatore(); // ... $this->getDoctrine()->getManager()->persist($giocatore); $this->getDoctrine()->getManager()->flush(); return $this->redirectToRoute('giocatori'); } return $this->render('giocatore/nuovo.html.twig', [ 'form' => $form->createView(), ]); }
  28. 28. No more Setters class Giocatore { public function __construct(Squadra $squadra, string $nome, int $numero) { $this->squadra = $squadra; $this->nome = $nome; $this->numeroDiMaglia = $numero; } // ... }
  29. 29. Action public function nuovoAction(Request $request) { $dto = new GiocatoreDTO(); $form = $this->createForm(GiocatoreType::class, $dto); if ($form->handleRequest($request)->isValid()) { $giocatore = new Giocatore($dto->squadra, $dto->nome, $dto->numeroDiMaglia); $this->getDoctrine()->getManager()->persist($giocatore); $this->getDoctrine()->getManager()->flush(); return $this->redirectToRoute('giocatori'); } return $this->render('giocatore/nuovo.html.twig', [ 'form' => $form->createView(), ]); }
  30. 30. ValueObject
  31. 31. ValueObject Un oggetto definito dai suoi attributi
  32. 32. ValueObject Un oggetto definito dai suoi attributi Due ValueObject sono uguali se i loro attributi sono uguali
  33. 33. NumeroDiMaglia class NumeroDimaglia() { private $numero; public function __construct(int $numero) { if ($numero < 0 || $numero > 99) { throw new DomainException('Il numero deve esere tra 0 e 99'); } $this->numero = $numero; } public function __toString() { return (string) $this->numero; } }
  34. 34. Entity con ValueObject class Giocatore { /* @ORMEmbedded(class=”NumeroDimaglia”) */ private $numeroDiMaglia; public function __construct( Squadra $squadra, string $nome, NumeroDiMaglia $numero ) { $this->squadra = $squadra; $this->nome = $nome; $this->numeroDiMaglia = $numero; } // ... }
  35. 35. Vantaggi ● tipo più esplicito
  36. 36. Vantaggi ● tipo più esplicito ● vincoli interni al dominio
  37. 37. Vantaggi ● tipo più esplicito ● vincoli interni al dominio ● entità meno appiattita sulla persistenza
  38. 38. Vantaggi ● tipo più esplicito ● vincoli interni al dominio ● entità meno appiattita sulla persistenza ● entità meno accoppiata al framework
  39. 39. Configurazione doctrine: orm: auto_mapping: false mappings: Entity: type: xml prefix: SportModelEntity dir: "%kernel.root_dir%/config/doctrine/Entity" is_bundle: false ValueObject: type: xml prefix: SportModelValueObject dir: "%kernel.root_dir%/config/doctrine/ValueObject" is_bundle: false
  40. 40. What’s next?
  41. 41. What’s next? ● implementare CQRS con CommandBus
  42. 42. What’s next? ● implementare CQRS con CommandBus ● plus: i Command sono già pronti (sono i nostri DTO)
  43. 43. That’s all!
  • PavelUsachev

    Jan. 30, 2017
  • jigen79

    Nov. 18, 2016
  • DavideDellErba1

    Nov. 4, 2016
  • AndreaGiannantonio

    Nov. 1, 2016
  • MarcoMasotti

    Oct. 29, 2016

SymfonyDay 2016

Views

Total views

916

On Slideshare

0

From embeds

0

Number of embeds

123

Actions

Downloads

15

Shares

0

Comments

0

Likes

5

×