SlideShare a Scribd company logo
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 MongoDB
MongoDB
 
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 Elasticsearch
Florian 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 sets
MongoDB
 
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 2015
Roy 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 sphinx
Adrian 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-steps
Matteo 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 Documents
MongoDB
 
Mongo Web Apps: OSCON 2011
Mongo Web Apps: OSCON 2011Mongo Web Apps: OSCON 2011
Mongo Web Apps: OSCON 2011
rogerbodamer
 
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
MongoDB
 
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
MongoDB
 
elasticsearch - advanced features in practice
elasticsearch - advanced features in practiceelasticsearch - advanced features in practice
elasticsearch - advanced features in practice
Jano 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 Basics
MongoDB
 
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 ElasticSearch
Pedro 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 engine
Michael Parker
 
Elements for an iOS Backend
Elements for an iOS BackendElements for an iOS Backend
Elements for an iOS Backend
Laurent 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 Developers
Kathy Brown
 
Php on the Web and Desktop
Php on the Web and DesktopPhp on the Web and Desktop
Php on the Web and Desktop
Elizabeth 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 #d8rules
Srijan Technologies
 
Learning to run
Learning to runLearning to run
Learning to run
dominion
 
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
Darwin 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 webapplications
Giuliano Iacobelli
 
Practical catalyst
Practical catalystPractical catalyst
Practical catalyst
dwm042
 
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
 
C#Portfolio
C#PortfolioC#Portfolio
C#Portfolio
Jeriel_Mikell
 
Introduction To Code Igniter
Introduction To Code IgniterIntroduction To Code Igniter
Introduction To Code Igniter
Amzad Hossain
 
CDI @javaonehyderabad
CDI @javaonehyderabadCDI @javaonehyderabad
CDI @javaonehyderabad
Prasad Subramanian
 
Exploring Symfony's Code
Exploring Symfony's CodeExploring Symfony's Code
Exploring Symfony's Code
Wildan 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 Code
Rowan 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 Deck
rICh 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

Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
ThousandEyes
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Tobias Schneck
 
Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
Frank van Harmelen
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
ControlCase
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
Product School
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
Product School
 
Elevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsElevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object Calisthenics
Dorra BARTAGUIZ
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Product School
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and back
Elena Simperl
 
UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4
DianaGray10
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
Jemma Hussein Allen
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
DianaGray10
 
Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........
Alison B. Lowndes
 
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
UiPathCommunity
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Jeffrey Haguewood
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Ramesh Iyer
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Thierry Lestable
 
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
Product School
 

Recently uploaded (20)

Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
 
Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
 
PCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase TeamPCI PIN Basics Webinar from the Controlcase Team
PCI PIN Basics Webinar from the Controlcase Team
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
 
Elevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object CalisthenicsElevating Tactical DDD Patterns Through Object Calisthenics
Elevating Tactical DDD Patterns Through Object Calisthenics
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and back
 
UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
 
Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........
 
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
Dev Dives: Train smarter, not harder – active learning and UiPath LLMs for do...
 
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdfFIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
FIDO Alliance Osaka Seminar: FIDO Security Aspects.pdf
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
 
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
 

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