Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Software design patterns in the Symfony world

1768d238acf404dadd501ba424d65bfd?s=47 dknx01
August 01, 2019

Software design patterns in the Symfony world

1768d238acf404dadd501ba424d65bfd?s=128

dknx01

August 01, 2019
Tweet

Transcript

  1. Developer waiting for a talk

  2. Design Patterns and where to find them in Symfony Symfony

    User Group Berlin Erik Witthauer
  3. About me Erik Witthauer PHP developer for > 10 years

    Twitter: ewnx01 Web aka: dknx01 Speakerdeck: speackerdeck.com/dknx01 work: FTI
  4. Design pattern

  5. A short excursion only

  6. Design pattern • General, reusable solution to a commonly occurring

    problem within a given context in software design • A template or description of how to solve a problem, NOT code directly
  7. Design pattern

  8. Creational pattern responsible for encapsulating the producing and assembling of

    objects • Abstract Factory • Builder • Factory Method • Prototype • Singleton
  9. Structual pattern organize classes in a way to separate their

    implementations from their interfaces • Adapter • Bridge • Composite • Decorator • Facade • Proxy
  10. Behavioral pattern organize objects to make them collaborate together while

    reducing their coupling • Chain of Responsibility • Command • Interpreter • Iterator • Mediator • Memento • Observer • State • Strategy
  11. Pros • Communication • Code Testability • Maintainability • Loose

    Coupling • ... • Hard to Teach • Hard to Learn • Hard to Apply • Entry Barrier • ... Cons
  12. Builder Pattern

  13. Builder pattern • Flexible solution to various object creation of

    problems • Separate the construction of a complex object from its representation • Simplify class creation for classes with complex object(s) • Same Builder can create different class representations with the same process • Always creating a valid object, NOT the right object • Methods names are not predefined, but should be easy to understand
  14. • Allows you to vary an objects internal representation •

    Encapsulates code for construction and representation • Provides control over steps of construction process • Easier reusability of object instantiation • Requires creating a separate ConcreteBuilder for each different type of object • Requires the builder classes to be mutable • Data members of class aren't guaranteed to be initialized • Dependency injection may be less supported Advantages Disadvantages
  15. None
  16. Builder pattern - Doctrine QueryBuilder • provide a simple way

    to create a query object from a repository • Database independent $query = $this->createQueryBuilder('u, p') ->leftJoin('u.profile', 'p') ->where('LOWER(u.emailAddress) = :email') ->andWhere('u.active = :active') ->setParameter('email', mb_strtolower($email)) ->setParameter('active', 1) ->getQuery(); return $query->getOneOrNullResult();
  17. Builder pattern - Symfony FormBuilder • provide a simplier way

    to create a form instance class RegistrationType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder->add('emailAddress', EmailType::class) ->add('firstName', TextType::class) ->add('lastName', TextType::class) ->add('password', RepeatedType::class, [ 'type' => PasswordType::class, ]) ->add('submit', SubmitType::class); } }
  18. Chain of responsibility

  19. Chain of responsibility • Decoupling the sender of a request

    to its receivers • It should be possible that more than one receiver can handle a request • Define a chain of receiver objects having the responsibility, depending on run-time conditions, to either handle a request or forward it to the next receiver on the chain (if any)
  20. Chain of responsibility - Symfony voters • most granular way

    of checking permissions abstract class Voter implements VoterInterface { abstract protected function supports($attribute, $subject); abstract protected function voteOnAttribute($attribute, $subject, TokenInterface $token); } class PostController extends AbstractController { public function show($id) { // check for "view" access: calls all voters $this->denyAccessUnlessGranted('view', $post); }
  21. Chain of responsibility - Symfony voters class PostVoter extends Voter

    { protected function supports($attribute, $subject) { // only vote on Post objects inside this voter // if the attribute is one we support } protected function voteOnAttribute($attribute, $subject, TokenInterface $token) { // … some logic will be here }
  22. Adapter pattern

  23. Adapter pattern • Converts the (incompatible) interface of a class

    (adaptee) into another interface (target) the client require • Work through an adapter to work with (reuse) classes that do not have the required interface • makes two incompatible objects work together without changing their interfaces
  24. Adapter pattern

  25. Adapter pattern - HttpClient final class HttpClient { public static

    function create(...): HttpClientInterface { if (\extension_loaded('curl')) { // … return new CurlHttpClient($defaultOptions, $maxHostConnections, $maxPendingPushes); // ... } // native PHP stream return new NativeHttpClient($defaultOptions, $maxHostConnections); } }
  26. Interpreter pattern

  27. Interpreter pattern • used to define the grammar for instructions

    that form part of a language or notation, whilst allowing the grammar to be easily extended
  28. Interpreter pattern - Expression language $expressionLanguage = new ExpressionLanguage(); var_dump($expressionLanguage->evaluate('1

    + 2')); // displays 3 # config/services.yaml services: # ... App\Mail\MailerConfiguration: ~ App\Mailer: arguments: ["@=service('App\\\\Mail\\\\MailerConfiguration').getMailerMethod()"] App\Mailer: arguments: ["@=container.hasParameter('some_param') ? parameter('some_param') : 'default_value'"]
  29. Mediator pattern

  30. Mediator pattern • reduces coupling between classes that communicate with

    each other. Instead of classes communicating directly, and thus requiring knowledge of their implementation, the classes send messages via a mediator object
  31. Mediator pattern - EventDispatcher class EventDispatcher implements EventDispatcherInterface { private

    $listeners = []; public function addListener(string $eventName, callable $listener, int $priority = 0) { $this->listeners[$eventName][$priority][] = $listener; } } public function dispatch($eventName, Event $event = null) { $event = $event ?: new Event(); if ($listeners = $this->getListeners($eventName)) { $this->doDispatch($listeners, $eventName, $event); } } }
  32. Mediator pattern - EventDispatcher class OrderService { public function recordPayment(Payment

    $payment): void { // ... if ($order->isFullyPaid()) { $this->dispatcher->dispatch('order.paid', new OrderEvent($order)); } // … } }
  33. For today

  34. Links • https://en.wikipedia.org/wiki/Software_design_pattern • https://speakerdeck.com/hhamon/learning-design-patterns-with-symfony • https://refactoring.guru/design-patterns/

  35. Question and talk time

  36. End