SlideShare a Scribd company logo
Symfony e l' 

Architettura Esagonale
Software Developer, father, geek, PHP and
Node.js expert. Open-source enthusiast,
active contributor on GitHub and
StackOverflow.
Who am I?
Alessandro Minoccheri
Software developer @Flowing
@minompi
@AlessandroMinoccheri
◆
A real story
◆
◆
Come viene creato di solito un progetto Symfony?
• Installazione del Symfony skeleton project
• Rimozione del codice demo
• Autogenerazione delle entitá
• Autogenerazione dei controller
• Pronti a sviluppare l’applicazione
Hexagonal architecture ita
6 mesi dopo…
◆
◆
Quanti punti nel codice dobbiamo
modificare per sostituire quel
servizio?
◆
42 differenti posti in tutta la code-
base.
◆
class PaymentController
{
public function payAction(Request $request, YourBankGateway $gateway)
{
$gateway->pay($request->get('amount'), false, false, 0, 'EUR');
}
}
class Payment
{
public function pay(Request $request)
{
$gateway = new YourBankGateway();
$gateway->pay($request->get('amount'), false, false, 0);
}
}
class User
{
public function pay(Request $request)
{
$gateway = new YourBankGateway();
$gateway->pay($request->get('amount'));
}
}
Come mai esiste questa
situazione?
◆
I problemi nell’essere guidati dal framework
• Impossibilitá di aggiornare il framework e i vendors.
• Costi di manutenzione.
• Sviluppatori non motivati per I problemi del vecchio stack citato nel
punto 1.
• Applicazione non manutenibile perché c’é un forte accoppiamento.
• Molto debito tecnico.
• Impossibilitá di cambiare le implementazioni facilmente.
Quindi cosa é realmente
importante nel software?
◆
Ciò che apporta davvero valore nel
software è la soluzione al
problema specifico nel dominio
◆
Un pó di storia dell’Architettura
Esagonale
◆
L'architettura esagonale divide un sistema
in diversi componenti intercambiabili NON
accoppiati, come il core dell'applicazione,
il database, l'interfaccia utente, i test e le
interfacce con altri sistemi.
◆
E’ una sovra ingegnerizzazione?
◆
Codice Accoppiato
namespace AppService;
use SymfonyComponentHttpFoundationRequest;
class Payment
{
public function doPayment(Request $request)
{
$gateway = new YourBankGateway();
$gateway->pay($request->get('amount'), false, false, 0);
}
}
Codice disaccoppiato
interface GatewayProvider
{
public function pay(Money $amount): void;
}
Codice disaccoppiato
use AppValueObjectMoney;
class YourBankGateway implements GatewayProvider {
public function pay(Money $amount): void
{
//do stuff..
}
}
Codice disaccoppiato
class Payment
{
/**
* @var GatewayProvider
*/
private GatewayProvider $gatewayProvider;
public function __construct(GatewayProvider $gatewayProvider)
{
$this->gatewayProvider = $gatewayProvider;
}
public function doPayment(Money $amount)
{
$this->gatewayProvider->pay($amount);
}
}
Perchè è così importante
disaccoppiare il codice?
◆
Applicazione mantenibile
• Le modifiche in una parte di un'applicazione dovrebbero interessare
il minor numero possibile di altri punti
• L'aggiunta di funzionalità non dovrebbe richiedere di toccare
nessuna parte della base di codice
• L'aggiunta di nuovi modi per interagire con l'applicazione dovrebbe
richiedere il minor numero di modifiche possibile
• Il debug dovrebbe richiedere il minor numero di workaround
• I test dovrebbero essere relativamente facili
Single responsibility é anche per l'
architettura:

ciò che cambia per lo stesso motivo,
dovrebbe essere raggruppato insieme
◆
Esempi
• Codice relativo al framework
• Codice relativo ad uno specifico servizio
• Codice relativo al dominio
L'importante distinzione tra dominio e infrastruttura
Domain
• Modelli: entitá, value object o altro
• interfacce per I boundary objects
Infrastructure
• framework
• implementazione per boundary objects
• Web controllers, comandi CLI
Application
• Use cases
Perché é cosi importante avere un
software mantenibile?
◆
Perché un esagono?
Porte
◆
Le porte sono come i contratti
Non hanno rappresentazione nella codebase


C’é una porta per ogni use case dell’applicazione o codice che
interagisca con essa.
Ci sono porte di input e di output.
Input ports
interface PayOrderHandler
{
public function handle(PayOrderCommand $command): void;
}
Output ports
interface UserRepository
{
public function save(User $user): void;
public function findAll(): UserCollection;
}
Adapters
◆
Adapters definizione
Gli adapter sono le implementazioni delle porte, perché per ogni
porta abbiamo bisogno del codice che implementi i metodi.
Adapter esempio
class MysqlUserRepository implements UserRepository
{
/**
* @var Connection
*/
private $connection;
public function __construct(Connection $connection)
{
$this->connection = $connection;
}
public function save(User $user): void
{//do stuff...}
public function findById(UserId $userId): User
{//do stuff...}
public function findAll(): UserCollection
{//do stuff...}
}
Hexagonal architecture ita
Esempio di struttura di un progetto
Src
Payment
Domain

Application
Infrastructure
Cart
Domain
Application
Infrastructure
Dependency inversion principle
Vantaggi nell’uso dell’architettura
esagonale
◆
Incrementa la testabilitá
1
More unit tests
2


Puoi sostituire un implementazione senza toccare il dominio
3
Puoi prendere decisioni implementative piu tardi

come: vendors, databases, servers, etc…
4
Puoi aggiornare vendors e framework senza toccare il codice di
dominio.
5
Puoi creare applicazioni mantenibili
6
ESEMPIO
namespace AppUserInfrastructureController;
use AppUserApplicationCreateUserService;
use AppUserApplicationDTOCreateUserRequest;
use SymfonyComponentHttpFoundationJsonResponse;
use SymfonyComponentHttpFoundationRequest;
class UserController
{
public function saveAction(Request $request, CreateUserService $createUserService)
{
$createUserRequest = CreateUserRequest::create($request->request->all());
$createUserService->createUser($createUserRequest);
return new JsonResponse();
}
}
namespace AppUserApplication;
use …
class CreateUserService
{
private UserRepository $userRepository;
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
public function createUser(CreateUserRequest $createUserRequest): CreateUserResponse
{
$user = User::create(
$createUserRequest->getName(),
$createUserRequest->getPassword()
);
$this->userRepository->save($user);
return CreateUserResponse::createFromUser($user);
}
}
Quando usare questa architettura?
• Quando avete un progetto nuovo
• Quando devi sviluppare un nuovo contesto in una applicazione
legacy
• Sempre?
When to use it
Ma qual é l’approccio ai progetti
legacy che non usano
l’architettura esagonale?
◆
Regola d’oro
Regola del boy scout:

Lascia il tuo codice migliore rispetto a come l'hai trovato.
When to use it
Da dove possiamo partire?
• Usare piu interfacce possibili
• Usare la dependency injection
• Fare pratica con dei kata
• Applicare l’architettura esagonale a progetti reali
When to use it
Ulteriori miglioramenti
- DDD: Domain driven design
- CQRS pattern (Command Query Responsibility Segregation)
- Event sourcing
- TDD
- BDD
When to use it
We are hiring!
Thank you!
@minompi

More Related Content

PDF
Kotlin hexagonal-architecture
PPTX
Microservices
PPTX
Inversion of control e Dependency Injection (ITA)
PDF
Presentazione framework Symfony
PDF
The simplest thing that could possibly work
PPTX
AngularJS: server communication
PPTX
AngularJS – Reinventare le applicazioni web
PDF
Evoluzione del web development dalle cgi ai microservices
Kotlin hexagonal-architecture
Microservices
Inversion of control e Dependency Injection (ITA)
Presentazione framework Symfony
The simplest thing that could possibly work
AngularJS: server communication
AngularJS – Reinventare le applicazioni web
Evoluzione del web development dalle cgi ai microservices

Similar to Hexagonal architecture ita (20)

PDF
Designing with microservices - Daniele Mondello
PDF
Fare con Zend Framework 2 ciò che facevo con ZF1
PDF
AntiPatterns: i vizi del programmatore
PDF
PDF
L’evoluzione delle API: da CORBA a OpenAPI e oltre
PDF
Smau milano 2012 massimiliano del cero
PDF
La Unix Way vista da un DevOps
PPTX
Inversion of Control @ CD2008
PDF
PHP, non lo stesso vecchio linguaggio
PDF
AngularJS-Intro
PDF
Cac Es3 2009
PPT
Sviluppo Rapido Di Applicazioni Con Grails
PDF
DrupalDay 2014: AngularJS + IonicFramework + Drupal Services
PDF
DDAY2014 - Costruire una app mobile con Ionic, AngularJS ed ovviamente Drupal
PDF
Angularjs
PDF
Microsoft Azure for DreamSpark Academic Tour - 22/01/2016
PDF
Applicazioni distribuite con Symfony2
PDF
Smau milano 2012 arena social media matteo-collina
PDF
L'universo dietro alle App
PDF
Workshop Ideare e creare Web Applications, Introduzione ad AngularJS
Designing with microservices - Daniele Mondello
Fare con Zend Framework 2 ciò che facevo con ZF1
AntiPatterns: i vizi del programmatore
L’evoluzione delle API: da CORBA a OpenAPI e oltre
Smau milano 2012 massimiliano del cero
La Unix Way vista da un DevOps
Inversion of Control @ CD2008
PHP, non lo stesso vecchio linguaggio
AngularJS-Intro
Cac Es3 2009
Sviluppo Rapido Di Applicazioni Con Grails
DrupalDay 2014: AngularJS + IonicFramework + Drupal Services
DDAY2014 - Costruire una app mobile con Ionic, AngularJS ed ovviamente Drupal
Angularjs
Microsoft Azure for DreamSpark Academic Tour - 22/01/2016
Applicazioni distribuite con Symfony2
Smau milano 2012 arena social media matteo-collina
L'universo dietro alle App
Workshop Ideare e creare Web Applications, Introduzione ad AngularJS
Ad

More from Alessandro Minoccheri (8)

PDF
ServerSentEventsV2.pdf
PDF
ServerSentEvents.pdf
PDF
Hexagonal architecture
PDF
Smart working
PDF
ServerSentEventsV2.pdf
ServerSentEvents.pdf
Hexagonal architecture
Smart working
Ad

Hexagonal architecture ita

  • 1. Symfony e l' 
 Architettura Esagonale
  • 2. Software Developer, father, geek, PHP and Node.js expert. Open-source enthusiast, active contributor on GitHub and StackOverflow. Who am I? Alessandro Minoccheri Software developer @Flowing @minompi @AlessandroMinoccheri
  • 3.
  • 5.
  • 6. Come viene creato di solito un progetto Symfony? • Installazione del Symfony skeleton project • Rimozione del codice demo • Autogenerazione delle entitá • Autogenerazione dei controller • Pronti a sviluppare l’applicazione
  • 9.
  • 10. Quanti punti nel codice dobbiamo modificare per sostituire quel servizio? ◆
  • 11. 42 differenti posti in tutta la code- base. ◆
  • 12. class PaymentController { public function payAction(Request $request, YourBankGateway $gateway) { $gateway->pay($request->get('amount'), false, false, 0, 'EUR'); } }
  • 13. class Payment { public function pay(Request $request) { $gateway = new YourBankGateway(); $gateway->pay($request->get('amount'), false, false, 0); } }
  • 14. class User { public function pay(Request $request) { $gateway = new YourBankGateway(); $gateway->pay($request->get('amount')); } }
  • 15. Come mai esiste questa situazione? ◆
  • 16. I problemi nell’essere guidati dal framework • Impossibilitá di aggiornare il framework e i vendors. • Costi di manutenzione. • Sviluppatori non motivati per I problemi del vecchio stack citato nel punto 1. • Applicazione non manutenibile perché c’é un forte accoppiamento. • Molto debito tecnico. • Impossibilitá di cambiare le implementazioni facilmente.
  • 17. Quindi cosa é realmente importante nel software? ◆
  • 18. Ciò che apporta davvero valore nel software è la soluzione al problema specifico nel dominio ◆
  • 19. Un pó di storia dell’Architettura Esagonale ◆
  • 20. L'architettura esagonale divide un sistema in diversi componenti intercambiabili NON accoppiati, come il core dell'applicazione, il database, l'interfaccia utente, i test e le interfacce con altri sistemi. ◆
  • 21. E’ una sovra ingegnerizzazione? ◆
  • 22. Codice Accoppiato namespace AppService; use SymfonyComponentHttpFoundationRequest; class Payment { public function doPayment(Request $request) { $gateway = new YourBankGateway(); $gateway->pay($request->get('amount'), false, false, 0); } }
  • 23. Codice disaccoppiato interface GatewayProvider { public function pay(Money $amount): void; }
  • 24. Codice disaccoppiato use AppValueObjectMoney; class YourBankGateway implements GatewayProvider { public function pay(Money $amount): void { //do stuff.. } }
  • 25. Codice disaccoppiato class Payment { /** * @var GatewayProvider */ private GatewayProvider $gatewayProvider; public function __construct(GatewayProvider $gatewayProvider) { $this->gatewayProvider = $gatewayProvider; } public function doPayment(Money $amount) { $this->gatewayProvider->pay($amount); } }
  • 26. Perchè è così importante disaccoppiare il codice? ◆
  • 27. Applicazione mantenibile • Le modifiche in una parte di un'applicazione dovrebbero interessare il minor numero possibile di altri punti • L'aggiunta di funzionalità non dovrebbe richiedere di toccare nessuna parte della base di codice • L'aggiunta di nuovi modi per interagire con l'applicazione dovrebbe richiedere il minor numero di modifiche possibile • Il debug dovrebbe richiedere il minor numero di workaround • I test dovrebbero essere relativamente facili
  • 28. Single responsibility é anche per l' architettura:
 ciò che cambia per lo stesso motivo, dovrebbe essere raggruppato insieme ◆
  • 29. Esempi • Codice relativo al framework • Codice relativo ad uno specifico servizio • Codice relativo al dominio
  • 30. L'importante distinzione tra dominio e infrastruttura Domain • Modelli: entitá, value object o altro • interfacce per I boundary objects Infrastructure • framework • implementazione per boundary objects • Web controllers, comandi CLI Application • Use cases
  • 31. Perché é cosi importante avere un software mantenibile? ◆
  • 34. Le porte sono come i contratti Non hanno rappresentazione nella codebase 
 C’é una porta per ogni use case dell’applicazione o codice che interagisca con essa. Ci sono porte di input e di output.
  • 35. Input ports interface PayOrderHandler { public function handle(PayOrderCommand $command): void; }
  • 36. Output ports interface UserRepository { public function save(User $user): void; public function findAll(): UserCollection; }
  • 38. Adapters definizione Gli adapter sono le implementazioni delle porte, perché per ogni porta abbiamo bisogno del codice che implementi i metodi.
  • 39. Adapter esempio class MysqlUserRepository implements UserRepository { /** * @var Connection */ private $connection; public function __construct(Connection $connection) { $this->connection = $connection; } public function save(User $user): void {//do stuff...} public function findById(UserId $userId): User {//do stuff...} public function findAll(): UserCollection {//do stuff...} }
  • 41. Esempio di struttura di un progetto Src Payment Domain
 Application Infrastructure Cart Domain Application Infrastructure
  • 46. 
 Puoi sostituire un implementazione senza toccare il dominio 3
  • 47. Puoi prendere decisioni implementative piu tardi
 come: vendors, databases, servers, etc… 4
  • 48. Puoi aggiornare vendors e framework senza toccare il codice di dominio. 5
  • 49. Puoi creare applicazioni mantenibili 6
  • 51. namespace AppUserInfrastructureController; use AppUserApplicationCreateUserService; use AppUserApplicationDTOCreateUserRequest; use SymfonyComponentHttpFoundationJsonResponse; use SymfonyComponentHttpFoundationRequest; class UserController { public function saveAction(Request $request, CreateUserService $createUserService) { $createUserRequest = CreateUserRequest::create($request->request->all()); $createUserService->createUser($createUserRequest); return new JsonResponse(); } }
  • 52. namespace AppUserApplication; use … class CreateUserService { private UserRepository $userRepository; public function __construct(UserRepository $userRepository) { $this->userRepository = $userRepository; } public function createUser(CreateUserRequest $createUserRequest): CreateUserResponse { $user = User::create( $createUserRequest->getName(), $createUserRequest->getPassword() ); $this->userRepository->save($user); return CreateUserResponse::createFromUser($user); } }
  • 53. Quando usare questa architettura? • Quando avete un progetto nuovo • Quando devi sviluppare un nuovo contesto in una applicazione legacy • Sempre? When to use it
  • 54. Ma qual é l’approccio ai progetti legacy che non usano l’architettura esagonale? ◆
  • 55. Regola d’oro Regola del boy scout:
 Lascia il tuo codice migliore rispetto a come l'hai trovato. When to use it
  • 56. Da dove possiamo partire? • Usare piu interfacce possibili • Usare la dependency injection • Fare pratica con dei kata • Applicare l’architettura esagonale a progetti reali When to use it
  • 57. Ulteriori miglioramenti - DDD: Domain driven design - CQRS pattern (Command Query Responsibility Segregation) - Event sourcing - TDD - BDD When to use it