SlideShare a Scribd company logo
1 of 32
Download to read offline
Code decoupling from Symfony
(and others frameworks)
Miguel Gallardo
@mg3dem
Who I am?
• Miguel Gallardo

• Cordoba, Argentina

• Spent more than 15 years writing software

• Software Engineer @ ProPoint Solutions, LLC 

(http://propointglobal.com/)

• @mg3dem (twitter, linkedin, facebook, instagram)

• mgallardo@propointglobal.com
• Wrote a lot of Hello world scripts

• make it show dynamic content!

• Guestbook or todo list using a DB

• Inline HTML in php sucks, it becomes tedious to change logic. You
can separate both! presentation logic and the business logic. 

• Discover Libraries, there is a library for everything!

• what happens if we get together a lot of libraries? A framework!

• Everyone tries to make a framework!

• Frameworks becomes a must in php development
What’s next?
Decoupling?
–Wikipedia
“coupling is the degree of interdependence
between software modules; a measure of how
closely connected two routines or modules are; the
strength of the relationships between modules.”
 “cohesion refers to the degree to which the
elements inside a module belong together”
–Wikipedia
Benefits of decoupling
• Minimize dependency of external frameworks, libraries

• Minimize backward compatibility breaks

• More portable

• More reusable

• Easier to change implementations

• Easier to maintain

• Easier to test

• More clean code and architecture
Symfony
(Our aproach)
“The Framework Isn't a Part of Your Application”
• Frameworks come and go, especially in the PHP world

• There are dozens if not hundreds of PHP frameworks,
most of which no one has heard of

• The popular frameworks, well they have gone through
major revamps at least once in their lifetime

• people do is keep their code with the old framework,
sacrificing years of potential bug and security fixes for not
updating
– Christopher Stea
“The whole point of framework independence is to
protect our business logic from these scenarios and
one can even update to the latest framework with
ease without major rewrites”
Some rules
• All code MUST obey the Law of Demeter

• a given object should assume as little as possible about the structure or
properties of anything else.

• All code MUST follow the Single Responsibility Principal

• a given object should assume as little as possible about the structure or
properties of anything else.

• Software entities (classes, modules, functions, etc.)
should be open for extension, but closed for modification

• Can allow to be extended without modifying its source code
Entity
• Represents a single record of data

• Getters and Setters

• Can link to other entities that represent the relations
between them

• Must be independent of the hosting framework

• Must be kept lean with no business logic and no logic for
data persistence != ActiveRecord
<?php
class Customer
{
/**
* @var int
*/
private $id;
private $phoneNumber;
private $user;
/**
* @var CustomerStatus
*/
private $status;
public function __construct(User $user, int $phoneNumber) {}
public function getId(): ?int {}
public function getPhoneNumber(): int {}
/**
* Set status
*
* @param CustomerStatus $customerStatus CustomerStatus Entity.
*
* @return Customer
*/
public function setStatus(CustomerStatus $customerStatus): Customer
{
$this->status = $customerStatus;
return $this;
}
}
Repository
• Represents the data persistence layer

• Code pertaining to fetching and saving entities should be specified in the
repository

• Should be lean and free from business logic.

• It’s an Interface

• Implemented by data repository (DB abstraction layer, API
layer, etc)
<?php
namespace PropointSmsCustomerRepository;
use PropointSmsAccountEntityUser;
use PropointSmsCustomerEntityCustomer;
interface CustomerRepositoryInterface
{
/**
* Save customer entity.
*
* @param Customer $customer Customer entity.
*/
public function save(Customer $customer): void;
/**
* Get Customer record for a customer of a specific store.
*
* @param User $user User entity.
* @param int $phoneNumber Customer phone number.
*
* @return null|Customer
*/
public function getByPhoneNumber(User $user, int $phoneNumber): ?Customer;
/**
* Get all customer entries for a specified phone number
*
* @param int $phoneNumber Phone number.
*
* @return Customer[]
*/
public function getAllByPhoneNumber(int $phoneNumber): array;
}
Service
• Contains all of the business logic of an application

• Should be completely agnostic to data persistence

• Act as a abstraction layer for repositories

• May use other services for data retrieval

• But NOT to persist data

• Use event subscribers instead!

• Must be independent of the framework
<?php
class CustomerService implements PropointSmsCustomerCustomerServiceInterface
{
private $eventDispatcher;
private $customerRepository;
private $customerStatusRepository;
public function getStatus(string $statusName): CustomerStatus
{
return $this->customerStatusRepository->getByName($statusName);
}
public function create(User $user, int $phoneNumber): Customer
{
$customer = new Customer($user, $phoneNumber);
$customer->setStatus($this->getStatus('ACTIVE'));
return $customer;
}
public function getByPhoneNumber(User $user, int $phoneNumber): Customer
{
return $this->customerRepository->getByPhoneNumber($user, $phoneNumber);
}
public function save(Customer $customer): void
{
$this->customerRepository->save($customer);
if (empty($customer->getId())) { //New customer
$this->eventDispatcher->dispatch(CustomerCreated::NAME, new CustomerCreated($customer));
}
$this->eventDispatcher->dispatch(CustomerUpdated::NAME, new CustomerUpdated($customer));
}
}
Controller
• Focus on receiving an incoming HTTP request, fetching
incoming parameters and returning an HTTP response.

• Must be kept lean and free from business logic.

• Pass parameter to services for processing

• And use the results to generate a response.
<?php
class MessageController extends FOSRestBundleControllerFOSRestController
{
public function postIndexAction(
Request $request,
MessageServiceInterface $messageService,
CustomerServiceInterface $customerService,
UserServiceInterface $userService
): Response {
$payload = json_decode($request->getContent(), true);
try {
if (empty($payload)) {
throw new SymfonyComponentHttpKernelExceptionBadRequestHttpException(
'Invalid JSON in request body.'
);
}
try {
$user = $userService->getByUsername($this->getUser()->getUserName());
$message = $messageService->loadFromArray($user, $payload);
$customer = $customerService->getOrCreateCustomer($user, $message->getPhoneNumber());
$canSend = $customer->getStatus()->canSendSms();
if (!$canSend) {
$message->setStatus($messageService->getStatus('FORBIDDEN'));
}
$message->setCustomer($customer);
$messageService->save($message);
if (!$canSend) {
throw new SymfonyComponentHttpKernelExceptionAccessDeniedHttpException(
'Cannot send SMS to opt-out customer'
);
}
} catch (InvalidArgumentException $exception) {
throw new SymfonyComponentHttpKernelExceptionUnprocessableEntityHttpException(
$exception->getMessage(),
$exception
);….
What about libraries?
Don’t use decoupling
(everywhere)

it can be abused and its usefulness depends on the type of the project.
• Good protection against external changes, but doesn’t
mean that it should always be applied everywhere!

• We can’t always decouple from everything

• The decision of when to use it depends on the context 

(project, team, industry, etc)

• Be pragmatic: 

• use the right tool for the right job

• Doesn’t apply patterns without a problem solved by a design pattern
• Think of your modules as independent, as if the rest of
the program didn't exist

• Prefer abstractions - they tend to help you think of your
modules as independent

• Design patterns of course

• Cohesive code is often decoupled

• Prefer composition, over inheritance.

• Use layers of architecture
Thanks!
Miguel Gallardo
@mg3dem

More Related Content

What's hot

Back to Basics, webinar 2: La tua prima applicazione MongoDB
Back to Basics, webinar 2: La tua prima applicazione MongoDBBack to Basics, webinar 2: La tua prima applicazione MongoDB
Back to Basics, webinar 2: La tua prima applicazione MongoDBMongoDB
 
Introduction to MongoDB
Introduction to MongoDBIntroduction to MongoDB
Introduction to MongoDBAlex Bilbie
 
Data modeling for Elasticsearch
Data modeling for ElasticsearchData modeling for Elasticsearch
Data modeling for ElasticsearchFlorian Hopf
 
Back to Basics Spanish Webinar 3 - Introducción a los replica sets
Back to Basics Spanish Webinar 3 - Introducción a los replica setsBack to Basics Spanish Webinar 3 - Introducción a los replica sets
Back to Basics Spanish Webinar 3 - Introducción a los replica setsMongoDB
 
MongoDB : The Definitive Guide
MongoDB : The Definitive GuideMongoDB : The Definitive Guide
MongoDB : The Definitive GuideWildan Maulana
 
Elasticsearch - DevNexus 2015
Elasticsearch - DevNexus 2015Elasticsearch - DevNexus 2015
Elasticsearch - DevNexus 2015Roy Russo
 
Conceptos básicos. Seminario web 4: Indexación avanzada, índices de texto y g...
Conceptos básicos. Seminario web 4: Indexación avanzada, índices de texto y g...Conceptos básicos. Seminario web 4: Indexación avanzada, índices de texto y g...
Conceptos básicos. Seminario web 4: Indexación avanzada, índices de texto y g...MongoDB
 
Real time fulltext search with sphinx
Real time fulltext search with sphinxReal time fulltext search with sphinx
Real time fulltext search with sphinxAdrian Nuta
 
Elastify you application: from SQL to NoSQL in less than one hour!
Elastify you application: from SQL to NoSQL in less than one hour!Elastify you application: from SQL to NoSQL in less than one hour!
Elastify you application: from SQL to NoSQL in less than one hour!David Pilato
 
Использование Elasticsearch для организации поиска по сайту
Использование Elasticsearch для организации поиска по сайтуИспользование Elasticsearch для организации поиска по сайту
Использование Elasticsearch для организации поиска по сайтуOlga Lavrentieva
 
Elasticsearch first-steps
Elasticsearch first-stepsElasticsearch first-steps
Elasticsearch first-stepsMatteo Moci
 
Back to Basics Webinar 3: Schema Design Thinking in Documents
 Back to Basics Webinar 3: Schema Design Thinking in Documents Back to Basics Webinar 3: Schema Design Thinking in Documents
Back to Basics Webinar 3: Schema Design Thinking in DocumentsMongoDB
 
Mongo Web Apps: OSCON 2011
Mongo Web Apps: OSCON 2011Mongo Web Apps: OSCON 2011
Mongo Web Apps: OSCON 2011rogerbodamer
 
Conceptos básicos. Seminario web 5: Introducción a Aggregation Framework
Conceptos básicos. Seminario web 5: Introducción a Aggregation FrameworkConceptos básicos. Seminario web 5: Introducción a Aggregation Framework
Conceptos básicos. Seminario web 5: Introducción a Aggregation FrameworkMongoDB
 
Back to Basics Webinar 1: Introduction to NoSQL
Back to Basics Webinar 1: Introduction to NoSQLBack to Basics Webinar 1: Introduction to NoSQL
Back to Basics Webinar 1: Introduction to NoSQLMongoDB
 
elasticsearch - advanced features in practice
elasticsearch - advanced features in practiceelasticsearch - advanced features in practice
elasticsearch - advanced features in practiceJano Suchal
 
Webinar: Getting Started with MongoDB - Back to Basics
Webinar: Getting Started with MongoDB - Back to BasicsWebinar: Getting Started with MongoDB - Back to Basics
Webinar: Getting Started with MongoDB - Back to BasicsMongoDB
 
Webinaire 2 de la série « Retour aux fondamentaux » : Votre première applicat...
Webinaire 2 de la série « Retour aux fondamentaux » : Votre première applicat...Webinaire 2 de la série « Retour aux fondamentaux » : Votre première applicat...
Webinaire 2 de la série « Retour aux fondamentaux » : Votre première applicat...MongoDB
 
Fazendo mágica com ElasticSearch
Fazendo mágica com ElasticSearchFazendo mágica com ElasticSearch
Fazendo mágica com ElasticSearchPedro Franceschi
 
mongoDB Performance
mongoDB PerformancemongoDB Performance
mongoDB PerformanceMoshe Kaplan
 

What's hot (20)

Back to Basics, webinar 2: La tua prima applicazione MongoDB
Back to Basics, webinar 2: La tua prima applicazione MongoDBBack to Basics, webinar 2: La tua prima applicazione MongoDB
Back to Basics, webinar 2: La tua prima applicazione MongoDB
 
Introduction to MongoDB
Introduction to MongoDBIntroduction to MongoDB
Introduction to MongoDB
 
Data modeling for Elasticsearch
Data modeling for ElasticsearchData modeling for Elasticsearch
Data modeling for Elasticsearch
 
Back to Basics Spanish Webinar 3 - Introducción a los replica sets
Back to Basics Spanish Webinar 3 - Introducción a los replica setsBack to Basics Spanish Webinar 3 - Introducción a los replica sets
Back to Basics Spanish Webinar 3 - Introducción a los replica sets
 
MongoDB : The Definitive Guide
MongoDB : The Definitive GuideMongoDB : The Definitive Guide
MongoDB : The Definitive Guide
 
Elasticsearch - DevNexus 2015
Elasticsearch - DevNexus 2015Elasticsearch - DevNexus 2015
Elasticsearch - DevNexus 2015
 
Conceptos básicos. Seminario web 4: Indexación avanzada, índices de texto y g...
Conceptos básicos. Seminario web 4: Indexación avanzada, índices de texto y g...Conceptos básicos. Seminario web 4: Indexación avanzada, índices de texto y g...
Conceptos básicos. Seminario web 4: Indexación avanzada, índices de texto y g...
 
Real time fulltext search with sphinx
Real time fulltext search with sphinxReal time fulltext search with sphinx
Real time fulltext search with sphinx
 
Elastify you application: from SQL to NoSQL in less than one hour!
Elastify you application: from SQL to NoSQL in less than one hour!Elastify you application: from SQL to NoSQL in less than one hour!
Elastify you application: from SQL to NoSQL in less than one hour!
 
Использование Elasticsearch для организации поиска по сайту
Использование Elasticsearch для организации поиска по сайтуИспользование Elasticsearch для организации поиска по сайту
Использование Elasticsearch для организации поиска по сайту
 
Elasticsearch first-steps
Elasticsearch first-stepsElasticsearch first-steps
Elasticsearch first-steps
 
Back to Basics Webinar 3: Schema Design Thinking in Documents
 Back to Basics Webinar 3: Schema Design Thinking in Documents Back to Basics Webinar 3: Schema Design Thinking in Documents
Back to Basics Webinar 3: Schema Design Thinking in Documents
 
Mongo Web Apps: OSCON 2011
Mongo Web Apps: OSCON 2011Mongo Web Apps: OSCON 2011
Mongo Web Apps: OSCON 2011
 
Conceptos básicos. Seminario web 5: Introducción a Aggregation Framework
Conceptos básicos. Seminario web 5: Introducción a Aggregation FrameworkConceptos básicos. Seminario web 5: Introducción a Aggregation Framework
Conceptos básicos. Seminario web 5: Introducción a Aggregation Framework
 
Back to Basics Webinar 1: Introduction to NoSQL
Back to Basics Webinar 1: Introduction to NoSQLBack to Basics Webinar 1: Introduction to NoSQL
Back to Basics Webinar 1: Introduction to NoSQL
 
elasticsearch - advanced features in practice
elasticsearch - advanced features in practiceelasticsearch - advanced features in practice
elasticsearch - advanced features in practice
 
Webinar: Getting Started with MongoDB - Back to Basics
Webinar: Getting Started with MongoDB - Back to BasicsWebinar: Getting Started with MongoDB - Back to Basics
Webinar: Getting Started with MongoDB - Back to Basics
 
Webinaire 2 de la série « Retour aux fondamentaux » : Votre première applicat...
Webinaire 2 de la série « Retour aux fondamentaux » : Votre première applicat...Webinaire 2 de la série « Retour aux fondamentaux » : Votre première applicat...
Webinaire 2 de la série « Retour aux fondamentaux » : Votre première applicat...
 
Fazendo mágica com ElasticSearch
Fazendo mágica com ElasticSearchFazendo mágica com ElasticSearch
Fazendo mágica com ElasticSearch
 
mongoDB Performance
mongoDB PerformancemongoDB Performance
mongoDB Performance
 

Similar to Code decoupling from Symfony (and others frameworks) - PHP Conference Brasil 2017

Java on Google App engine
Java on Google App engineJava on Google App engine
Java on Google App engineMichael Parker
 
Elements for an iOS Backend
Elements for an iOS BackendElements for an iOS Backend
Elements for an iOS BackendLaurent Cerveau
 
Learning To Run - XPages for Lotus Notes Client Developers
Learning To Run - XPages for Lotus Notes Client DevelopersLearning To Run - XPages for Lotus Notes Client Developers
Learning To Run - XPages for Lotus Notes Client DevelopersKathy Brown
 
Php on the Web and Desktop
Php on the Web and DesktopPhp on the Web and Desktop
Php on the Web and DesktopElizabeth Smith
 
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rulesSrijan Technologies
 
Learning to run
Learning to runLearning to run
Learning to rundominion
 
Building Large Scale PHP Web Applications with Laravel 4
Building Large Scale PHP Web Applications with Laravel 4Building Large Scale PHP Web Applications with Laravel 4
Building Large Scale PHP Web Applications with Laravel 4Darwin Biler
 
Get things done with Yii - quickly build webapplications
Get things done with Yii - quickly build webapplicationsGet things done with Yii - quickly build webapplications
Get things done with Yii - quickly build webapplicationsGiuliano Iacobelli
 
Practical catalyst
Practical catalystPractical catalyst
Practical catalystdwm042
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...Fabio Franzini
 
Introduction To Code Igniter
Introduction To Code IgniterIntroduction To Code Igniter
Introduction To Code IgniterAmzad Hossain
 
Exploring Symfony's Code
Exploring Symfony's CodeExploring Symfony's Code
Exploring Symfony's CodeWildan Maulana
 
An Introduction to Tornado
An Introduction to TornadoAn Introduction to Tornado
An Introduction to TornadoGavin Roy
 
GDG Addis - An Introduction to Django and App Engine
GDG Addis - An Introduction to Django and App EngineGDG Addis - An Introduction to Django and App Engine
GDG Addis - An Introduction to Django and App EngineYared Ayalew
 
Living With Legacy Code
Living With Legacy CodeLiving With Legacy Code
Living With Legacy CodeRowan Merewood
 
PHP from soup to nuts Course Deck
PHP from soup to nuts Course DeckPHP from soup to nuts Course Deck
PHP from soup to nuts Course DeckrICh morrow
 
Osiąganie mądrej architektury z Symfony2
Osiąganie mądrej architektury z Symfony2 Osiąganie mądrej architektury z Symfony2
Osiąganie mądrej architektury z Symfony2 3camp
 

Similar to Code decoupling from Symfony (and others frameworks) - PHP Conference Brasil 2017 (20)

Java on Google App engine
Java on Google App engineJava on Google App engine
Java on Google App engine
 
.Net template solution architecture
.Net template solution architecture.Net template solution architecture
.Net template solution architecture
 
Elements for an iOS Backend
Elements for an iOS BackendElements for an iOS Backend
Elements for an iOS Backend
 
Learning To Run - XPages for Lotus Notes Client Developers
Learning To Run - XPages for Lotus Notes Client DevelopersLearning To Run - XPages for Lotus Notes Client Developers
Learning To Run - XPages for Lotus Notes Client Developers
 
Php on the Web and Desktop
Php on the Web and DesktopPhp on the Web and Desktop
Php on the Web and Desktop
 
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
[Srijan Wednesday Webinars] Ruling Drupal 8 with #d8rules
 
Learning to run
Learning to runLearning to run
Learning to run
 
Building Large Scale PHP Web Applications with Laravel 4
Building Large Scale PHP Web Applications with Laravel 4Building Large Scale PHP Web Applications with Laravel 4
Building Large Scale PHP Web Applications with Laravel 4
 
Get things done with Yii - quickly build webapplications
Get things done with Yii - quickly build webapplicationsGet things done with Yii - quickly build webapplications
Get things done with Yii - quickly build webapplications
 
Practical catalyst
Practical catalystPractical catalyst
Practical catalyst
 
WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...WebNet Conference 2012 - Designing complex applications using html5 and knock...
WebNet Conference 2012 - Designing complex applications using html5 and knock...
 
C#Portfolio
C#PortfolioC#Portfolio
C#Portfolio
 
Introduction To Code Igniter
Introduction To Code IgniterIntroduction To Code Igniter
Introduction To Code Igniter
 
CDI @javaonehyderabad
CDI @javaonehyderabadCDI @javaonehyderabad
CDI @javaonehyderabad
 
Exploring Symfony's Code
Exploring Symfony's CodeExploring Symfony's Code
Exploring Symfony's Code
 
An Introduction to Tornado
An Introduction to TornadoAn Introduction to Tornado
An Introduction to Tornado
 
GDG Addis - An Introduction to Django and App Engine
GDG Addis - An Introduction to Django and App EngineGDG Addis - An Introduction to Django and App Engine
GDG Addis - An Introduction to Django and App Engine
 
Living With Legacy Code
Living With Legacy CodeLiving With Legacy Code
Living With Legacy Code
 
PHP from soup to nuts Course Deck
PHP from soup to nuts Course DeckPHP from soup to nuts Course Deck
PHP from soup to nuts Course Deck
 
Osiąganie mądrej architektury z Symfony2
Osiąganie mądrej architektury z Symfony2 Osiąganie mądrej architektury z Symfony2
Osiąganie mądrej architektury z Symfony2
 

Recently uploaded

Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...HostedbyConfluent
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationRidwan Fadjar
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...gurkirankumar98700
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 

Recently uploaded (20)

Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
My Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 PresentationMy Hashitalk Indonesia April 2024 Presentation
My Hashitalk Indonesia April 2024 Presentation
 
SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 

Code decoupling from Symfony (and others frameworks) - PHP Conference Brasil 2017

  • 1. Code decoupling from Symfony (and others frameworks) Miguel Gallardo @mg3dem
  • 2. Who I am? • Miguel Gallardo • Cordoba, Argentina • Spent more than 15 years writing software • Software Engineer @ ProPoint Solutions, LLC 
 (http://propointglobal.com/) • @mg3dem (twitter, linkedin, facebook, instagram) • mgallardo@propointglobal.com
  • 3. • Wrote a lot of Hello world scripts • make it show dynamic content! • Guestbook or todo list using a DB • Inline HTML in php sucks, it becomes tedious to change logic. You can separate both! presentation logic and the business logic. • Discover Libraries, there is a library for everything! • what happens if we get together a lot of libraries? A framework! • Everyone tries to make a framework! • Frameworks becomes a must in php development
  • 6. –Wikipedia “coupling is the degree of interdependence between software modules; a measure of how closely connected two routines or modules are; the strength of the relationships between modules.”
  • 7.  “cohesion refers to the degree to which the elements inside a module belong together” –Wikipedia
  • 8. Benefits of decoupling • Minimize dependency of external frameworks, libraries • Minimize backward compatibility breaks • More portable • More reusable • Easier to change implementations • Easier to maintain • Easier to test • More clean code and architecture
  • 10. “The Framework Isn't a Part of Your Application”
  • 11. • Frameworks come and go, especially in the PHP world • There are dozens if not hundreds of PHP frameworks, most of which no one has heard of • The popular frameworks, well they have gone through major revamps at least once in their lifetime • people do is keep their code with the old framework, sacrificing years of potential bug and security fixes for not updating
  • 12. – Christopher Stea “The whole point of framework independence is to protect our business logic from these scenarios and one can even update to the latest framework with ease without major rewrites”
  • 13.
  • 14. Some rules • All code MUST obey the Law of Demeter • a given object should assume as little as possible about the structure or properties of anything else. • All code MUST follow the Single Responsibility Principal • a given object should assume as little as possible about the structure or properties of anything else. • Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification • Can allow to be extended without modifying its source code
  • 16. • Represents a single record of data • Getters and Setters • Can link to other entities that represent the relations between them • Must be independent of the hosting framework • Must be kept lean with no business logic and no logic for data persistence != ActiveRecord
  • 17. <?php class Customer { /** * @var int */ private $id; private $phoneNumber; private $user; /** * @var CustomerStatus */ private $status; public function __construct(User $user, int $phoneNumber) {} public function getId(): ?int {} public function getPhoneNumber(): int {} /** * Set status * * @param CustomerStatus $customerStatus CustomerStatus Entity. * * @return Customer */ public function setStatus(CustomerStatus $customerStatus): Customer { $this->status = $customerStatus; return $this; } }
  • 19. • Represents the data persistence layer • Code pertaining to fetching and saving entities should be specified in the repository • Should be lean and free from business logic. • It’s an Interface • Implemented by data repository (DB abstraction layer, API layer, etc)
  • 20. <?php namespace PropointSmsCustomerRepository; use PropointSmsAccountEntityUser; use PropointSmsCustomerEntityCustomer; interface CustomerRepositoryInterface { /** * Save customer entity. * * @param Customer $customer Customer entity. */ public function save(Customer $customer): void; /** * Get Customer record for a customer of a specific store. * * @param User $user User entity. * @param int $phoneNumber Customer phone number. * * @return null|Customer */ public function getByPhoneNumber(User $user, int $phoneNumber): ?Customer; /** * Get all customer entries for a specified phone number * * @param int $phoneNumber Phone number. * * @return Customer[] */ public function getAllByPhoneNumber(int $phoneNumber): array; }
  • 22. • Contains all of the business logic of an application • Should be completely agnostic to data persistence • Act as a abstraction layer for repositories • May use other services for data retrieval • But NOT to persist data • Use event subscribers instead! • Must be independent of the framework
  • 23. <?php class CustomerService implements PropointSmsCustomerCustomerServiceInterface { private $eventDispatcher; private $customerRepository; private $customerStatusRepository; public function getStatus(string $statusName): CustomerStatus { return $this->customerStatusRepository->getByName($statusName); } public function create(User $user, int $phoneNumber): Customer { $customer = new Customer($user, $phoneNumber); $customer->setStatus($this->getStatus('ACTIVE')); return $customer; } public function getByPhoneNumber(User $user, int $phoneNumber): Customer { return $this->customerRepository->getByPhoneNumber($user, $phoneNumber); } public function save(Customer $customer): void { $this->customerRepository->save($customer); if (empty($customer->getId())) { //New customer $this->eventDispatcher->dispatch(CustomerCreated::NAME, new CustomerCreated($customer)); } $this->eventDispatcher->dispatch(CustomerUpdated::NAME, new CustomerUpdated($customer)); } }
  • 25. • Focus on receiving an incoming HTTP request, fetching incoming parameters and returning an HTTP response. • Must be kept lean and free from business logic. • Pass parameter to services for processing • And use the results to generate a response.
  • 26. <?php class MessageController extends FOSRestBundleControllerFOSRestController { public function postIndexAction( Request $request, MessageServiceInterface $messageService, CustomerServiceInterface $customerService, UserServiceInterface $userService ): Response { $payload = json_decode($request->getContent(), true); try { if (empty($payload)) { throw new SymfonyComponentHttpKernelExceptionBadRequestHttpException( 'Invalid JSON in request body.' ); } try { $user = $userService->getByUsername($this->getUser()->getUserName()); $message = $messageService->loadFromArray($user, $payload); $customer = $customerService->getOrCreateCustomer($user, $message->getPhoneNumber()); $canSend = $customer->getStatus()->canSendSms(); if (!$canSend) { $message->setStatus($messageService->getStatus('FORBIDDEN')); } $message->setCustomer($customer); $messageService->save($message); if (!$canSend) { throw new SymfonyComponentHttpKernelExceptionAccessDeniedHttpException( 'Cannot send SMS to opt-out customer' ); } } catch (InvalidArgumentException $exception) { throw new SymfonyComponentHttpKernelExceptionUnprocessableEntityHttpException( $exception->getMessage(), $exception );….
  • 27.
  • 29. Don’t use decoupling (everywhere) it can be abused and its usefulness depends on the type of the project.
  • 30. • Good protection against external changes, but doesn’t mean that it should always be applied everywhere! • We can’t always decouple from everything • The decision of when to use it depends on the context 
 (project, team, industry, etc) • Be pragmatic: • use the right tool for the right job • Doesn’t apply patterns without a problem solved by a design pattern
  • 31. • Think of your modules as independent, as if the rest of the program didn't exist • Prefer abstractions - they tend to help you think of your modules as independent • Design patterns of course • Cohesive code is often decoupled • Prefer composition, over inheritance. • Use layers of architecture