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

Software design patterns in the Symfony world

dknx01
August 01, 2019

Software design patterns in the Symfony world

dknx01

August 01, 2019
Tweet

More Decks by dknx01

Other Decks in Programming

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