Decouple your framework now, thank me later

43
DECOUPLE YOUR FRAMEWORK NOW, THANK ME LATER MICHELANGELO VAN DAM - @DRAGONBE

Transcript of Decouple your framework now, thank me later

Page 1: Decouple your framework now, thank me later

DECOUPLE YOUR FRAMEWORK NOW, THANK ME LATERMICHELANGELO VAN DAM - @DRAGONBE

Page 2: Decouple your framework now, thank me later

MICHELANGELO VAN DAM

CEO at in2it Lead PHP architect Community leader Coach & mentor FOSS contributor Public speaker

Page 3: Decouple your framework now, thank me later

FRAMEWORKS ARE GREAT!

• They abstract common tasks like email, database connectivity, routing and a ton more…

• They allow us to quickly develop complex applications

• They offer good to great security and robustness

Page 4: Decouple your framework now, thank me later

BUT…

• Frameworks have a nasty aftertaste when building business logic

• You need to use their database, log or cache adapter everywhere

• View templates are requiring framework components like translations, escaping and other trivial purposes

• Best practices require to use modules, bundles or features to separate business logic components

Page 5: Decouple your framework now, thank me later

IMPROVEMENTS THROUGH STANDARDS

• The PHP-FIG standards motivates frameworks to use great components to abstract functionality and ensure interoperability with other frameworks and tools

• Major frameworks already offer this straight off the bat

• But add their own “secret sauce” to link it within their framework, even when using Dependency Injection

Page 6: Decouple your framework now, thank me later

WHAT ARE THE CHALLENGES?

Page 7: Decouple your framework now, thank me later

UPGRADE (OR CHANGE) YOUR FRAMEWORK

Page 8: Decouple your framework now, thank me later

UPGRADE TO THE LATEST PHP VERSION

Page 9: Decouple your framework now, thank me later

BUSINESS LOGIC AND FRAMEWORKS MIXED

Framework X Business Logic

BL DB

FW DB

FW Logging

FW Mail

FW Service

BL Logging

BL Mail

BL Services

Page 10: Decouple your framework now, thank me later

APPLYING INTERFACES IN BETWEEN

Framework X Business Logic

FW DB

FW Logging

FW Mail

FW Service

BL DB

BL Logging

BL Mail

BL Services

DB Interface

Logging Interface

Mail Interface

Service Interface

Page 11: Decouple your framework now, thank me later

RESTAURANT PRINCIPLE

Page 12: Decouple your framework now, thank me later

THE HOSTESWILL BRING YOU TO YOUR TABLE AND GIVES YOU THE MENU AND WINE LIST.

Page 13: Decouple your framework now, thank me later

A WAITERWILL TAKE YOUR ORDER FOR DRINKS AND FOOD

Page 14: Decouple your framework now, thank me later

BARTENDERWILL PREPARE YOUR DRINKS

Page 15: Decouple your framework now, thank me later

KITCHENWILL PREPARE YOUR MEAL

Page 16: Decouple your framework now, thank me later

YOUR WAITERBRINGS YOUR DRINKS

Page 17: Decouple your framework now, thank me later

YOUR WAITERWILL DELIVER YOUR FOOD

Page 18: Decouple your framework now, thank me later

YOUR WAITERWILL GIVE YOU THE BILL WHEN DONE

Page 19: Decouple your framework now, thank me later
Page 20: Decouple your framework now, thank me later

YOUR WAITER

• Interfaces with the hostess to get started

• Interfaces with you to take your order

• Interfaces with the bar for drinks

• Interfaces with the cash register to present you a bill

Page 21: Decouple your framework now, thank me later

YOUR WAITER

• Receives notification you have arrived at your table

• Receives your order from you

• Receives drinks from the bartender

• Receives food from the kitchen

• Receives money from you

Page 22: Decouple your framework now, thank me later

HOW DO WE DO THIS IN CODE?

Page 23: Decouple your framework now, thank me later

INTERFACESDESIGN BY CONTRACTS

Page 24: Decouple your framework now, thank me later

WHAT ARE INTERFACES

• Interfaces define a requirement without concrete implementation

• There’s no limit on interfaces implemented

• Everyone understands the “contract” immediately

• One interface per goal, feature or purpose

Page 25: Decouple your framework now, thank me later

COMMON INTERFACES IN PHP

• Countable

• Iterator (and derivates)

• See language.oop5.interfaces on php.net for more details!

Page 26: Decouple your framework now, thank me later

CUSTOM INTERFACES

interface TableGatewayInterface {     public function find(int $id): array;

    public function fetchRow(         array $where = [],          array $order = []     ): array;

    public function fetchAll(         array $where = [],          array $order = [],          int $count = 0,          int $offset = 0     ): array;

    public function insert(array $data): int;

    public function update(array $data, array $where = []): int; }

Page 27: Decouple your framework now, thank me later

BONUS: VERY TESTABLE!!!

• No need to implement concrete code, just use interfaces to guide your development

• A class can implement multiple interfaces, testing can occur on a single interface functionality at a time.

Page 28: Decouple your framework now, thank me later

EVENTS

Page 29: Decouple your framework now, thank me later

WHAT ARE EVENTS?

• Events allow us to run tasks in the background and call back when completed.

• Implements the observer pattern (e.g. SplSubject & SplObserver)

• One observer can have many subscribers

• A subscriber can subscribe to many observer objects

Page 30: Decouple your framework now, thank me later

EXAMPLE

$memberService = new MemberService(); $memberService->attach(new DBObserver()); $memberService->attach(new LogObserver()); $memberService->attach(new EmailObserver()); $memberService->attach(new CacheObserver()); $memberService->attach(new SearchObserver()); $memberService->register(new Member('John', 'Doe', '[email protected]'));

Page 31: Decouple your framework now, thank me later

EVENT OBSERVATION

Register

DB

Log

Email

Cache

Search

Storing in DB

Logging

Sending email

Write to cache

Update indexes

Page 32: Decouple your framework now, thank me later

EVENT OBSERVATION AFTER EVENTS

Register

DB

Log

Email

Cache

Search

Storing in DB

Logging

Sending email

Write to cache

Update indexes

Page 33: Decouple your framework now, thank me later

BENEFITS

• Reusable logic

• Runs in the background, so no delays

• Scalable

Page 34: Decouple your framework now, thank me later

GLUING ALL TOGETHER

Page 35: Decouple your framework now, thank me later

Core Business Logic

Silex Web Frontend

Apigility API

Phalcon Web Backend

Page 36: Decouple your framework now, thank me later

Core Business Logic

Slim Web Frontend

Zend Expressive

API

Python Web Backend

Page 37: Decouple your framework now, thank me later

GLUE CLASS TO INTERACT 1/3

class SilexServiceProvider implements ServiceProviderInterface {     public function register(Container $container)     {         $dsn = $container['cb_config_db.dsn'] ?: '';         $username = $container['cb_config_db.username'] ?: '';         $password = $container['cb_config_db.password'] ?: '';         $pdo = new \PDO($dsn, $username, $password);

        $authorTable = new AuthorTable($pdo);         $authorHydrator = new AuthorHydrator();         $author = new Author();

        $bookTable = new BookTable($pdo);         $bookHydrator = new BookHydrator();         $book = new Book();                  $memberTable = new MemberTable($pdo);         $memberHydrator = new MemberHydrator();         $member = new Member();

Page 38: Decouple your framework now, thank me later

GLUE CLASS TO INTERACT 2/3

        $serviceLocator = new ServiceLocator();         $serviceLocator             ->set('\Cloudbooks\Author\Model\AuthorTable', $authorTable)             ->set('\Cloudbooks\Author\Model\AuthorHydrator', $authorHydrator)             ->set('\Cloudbooks\Author\Entity\Author', $author)             ->set('\Cloudbooks\Book\Model\BookTable', $bookTable)             ->set('\Cloudbooks\Book\Model\BookHydrator', $bookHydrator)             ->set('\Cloudbooks\Book\Entity\Book', $book)             ->set('\Cloudbooks\Member\Model\MemberTable', $memberTable)             ->set('\Cloudbooks\Member\Model\MemberHydrator', $memberHydrator)             ->set('\Cloudbooks\Member\Entity\Member', $member);    }

Page 39: Decouple your framework now, thank me later

GLUE CLASS TO INTERACT 3/3

        $container['cb_author_service'] = $container->factory(function () use ($serviceLocator) {             $serviceFactory = new AuthorServiceFactory();             return $serviceFactory->createService($serviceLocator);         });         $container['cb_book_service'] = $container->factory(function () use ($serviceLocator) {             $serviceFactory = new BookServiceFactory();             return $serviceFactory->createService($serviceLocator);         });         $container['cb_member_service'] = $container->factory(function () use ($serviceLocator) {             $serviceFactory = new MemberServiceFactory();             return $serviceFactory->createService($serviceLocator);         });     }

Page 40: Decouple your framework now, thank me later

LET’S RECAP

Page 41: Decouple your framework now, thank me later
Page 42: Decouple your framework now, thank me later

https://github.com/sensiolabs-de/deptrac

Page 43: Decouple your framework now, thank me later

THANK YOU!