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

Designing for Change: ​ Extensibility points in...

Avatar for Adam Wójs Adam Wójs
December 17, 2024
24

Designing for Change: ​ Extensibility points in practice​ ​

Avatar for Adam Wójs

Adam Wójs

December 17, 2024
Tweet

Transcript

  1. $ whoami Adam Wójs • Director of Engineering @ Ibexa

    • > 14 years of experience • Working with PHP ecosystem /adamwojs /adamwojs /adamwojs
  2. What is Ibexa DXP ? • CMS + PIM &

    Commerce + Personalization • Based on Symfony • Highly customizable • 90+ composer packages • 350+ REST endpoints • 1,6+ mln lines of codes (*.php)
  3. What is an Extension Point? Extension Point is a code

    designed and introduced to enable customization of a functionality without altering the original codebase.
  4. What is an Extension Point? Extension Point is a code

    designed and introduced to enable customization of a functionality without altering the original codebase.
  5. What is an Extension Point? Extension Point is a code

    designed and introduced to enable customization of a functionality without altering the original codebase.
  6. Events Use case 1. Customize default logic 2. Notifications Infrastructure

    code ★★☆ (provided by symfony/event-dispatcher component) Steps to introduce 1. Create event class 2. Dispatch event 3. Process result (if applicable) Comments Can be used inside of the core logic and works with multiple clients by default
  7. Example: kernel.controller event Description • Dispatched while processing request, after

    the controller has been resolved but before executing it • Used to initialize things or change the controller just before the controller is executed Example usage Collecting profiler data about routing (see Symfony\Component\HttpKernel\DataCollector\RequestDataCollector) Source symfony/http-kernel package
  8. Events: best practices • Provide documentation on when a given

    event is dispatched and how to change its outcome (if applicable) • Group related events by introducing base class or marker interface. For example. For example: 1. Symfony\Component\Form\FormEvent 2. Symfony\Component\HttpKernel\Event\KernelEvent 3. Symfony\Component\Workflow\Event\Event
  9. Decorators Use case Add new behaviors on top of existing

    objects Infrastructure code ★☆☆ (provided by symfony/dependency-injection component) Steps to introduce 1. Extract an interface 2. Register the service using interface FQCN introduced in a previous point as an alias to concreate implementation. 3. Provide abstract decorator (optional) Comments N/A
  10. Abstract decorators • An abstract decorator is an abstract class

    that implements a decorated interface and delegates execution to the decorated instance. • Eliminates boilerplate code in client implementations when decorating complex interfaces. • Must-have for complex interfaces
  11. Example: EntityManagerDecorator Description • The EntityManager is the central access

    point to ORM functionality. • Doctrine\ORM\EntityManagerInterface declares 27 methods + 8 inherited methods • Doctrine ORM provides abstract decorator for EntityManagerInterface: Doctrine\ORM\Decorator\EntityManagerDecorator Source: doctrine/orm package
  12. Example: EntityManagerDecorator You should never attempt to inherit from the

    EntityManager: Inheritance is not a valid extension point for the EntityManager. Instead you should take look at the \Doctrine\ORM\Decorator\EntityManagerDecorator and wrap your entity manager in a decorator. Source: https://github.com/doctrine/orm/blob/3.3.x/src/EntityManager.php#L53-L56
  13. Decorators: best practices • Provide interface for a services which

    are indented to be decorated. Expose them as a contract. • Create abstract decorator in case of the complex interfaces • Avoid decoration for a combination of main interfaces and optional feature interfaces
  14. Strategy Use case Define a family of interchangeable algorithms Infrastructure

    code ★★☆ (provided by symfony/dependency-injection component) Steps to introduce 1. Introduce strategy interface 2. Implement out-of-the-box implementations (optional) 3. Register service with tag of your choice 4. Use the right strategy Comments N/A
  15. Example: Placeholder Provider Description Generating placeholders if image is missing

    or unavailable Example usage • Ibexa\Bundle\Core\Imagine\PlaceholderProvider\GenericProvider • Ibexa\Bundle\Core\Imagine\PlaceholderProvider\RemoteProvider Source ibexa/core package
  16. Strategy registry Use case • Listing available strategies • Selecting

    strategy based on configuration • Adding & removing strategies in runtime Infrastructure code ★★★ (custom code) Steps to introduce 1. Introduce registry class along side with corresponding interface Comments N/A
  17. Example: Payment method type registry Description Access to all available

    strategies Example usage • Ibexa\Bundle\Payment\Form\Type\PaymentMethodTypeChoiceType Source ibexa/payment package
  18. Strategy: best practices • Strategy interface alongside with the corresponding

    service tag should be considered as a contract • Introduce registry if you want to give a client access to manage available strategies from runtime
  19. Cost of extension point Code Complexity Extension points requires additional

    abstractions. Testing Complexity You need to account for various customization scenarios during testing. Maintenance Effort Once an extension point is established, removing or modifying it can break existing customizations. Extension point requires extensive documentation. … but they come with a cost:
  20. Summary • Extension points is a code introduced to enable

    customization without altering the original codebase • Design patterns are foundation of extensibility. Both symfony/event- dispatcher & symfony/dependency-injection components provides necessary infrastructure code for extension points in most cases • Extension points are easy to introduce, but they come with a cost of increased code & testing complexity as well as extra maintenance effort
  21. Q&A