From silex to symfony and viceversa

61
From Silex to Symfony and viceversa PHP Barcelona Monthly Talks

Transcript of From silex to symfony and viceversa

From Silex to Symfony and viceversa

PHP Barcelona Monthly Talks

About me

Ronny López @ronnylt

Tech Lead – Social Point Stuff Doer – Tango Tree

Opinions are my own

Agenda• Introduction

• The “promise”

• Detecting violations

• The conclusions

• Some code

We are all aspiring software craftsmen

Aren’t we?

We want to build, not only working software, but also

well-crafted software

The reality• Lack of discipline

• Time pressures

• Long release cycles

• Short release cycles

• New features every day

• Bugs and hot fixes

Some of the implications…

• Infiltration of business logic into the delivery mechanism (or the user interface)

• Untestable systems

• Bad written tests

• Delayed projects

The attempted solution

“Create a new layer in the architecture…

With the promise that this time…

really and truly,

no business logic will be put into the new layer”

Day 0 what you think it is

the reallity

and finally…

• If we don’t have a mechanism to detect when a violation of that promise occurs…

• Then… in a few development cycles, the new layer is cluttered with business logic and the old problem has reappeared

The Pattern:“Ports and Adapters”

Alternative name: “Hexagonal

Architecture”

Ports and Adapters• Makes the application domain model central to the

system

• Cleanly decouples and isolates the application domain model from the system's technical infrastructure

• Define its relationships with the outside world in terms of application domain concepts ("ports")

http://www.natpryce.com/articles/000772.html

ApplicationHTTPAdapter

Application

Silex

Symfony

Silex vs Symfony?

No, not reallyThis is not the big question

It’s an implementation detail

It is just (one) of the delivery mechanisms

Application

HTTP/S

WS/S

Raw Sockets

Tests

CLI

Adapters

IPC

Application

HTTP/S

WS/S

Raw Sockets

Tests

CLI

Adapters

IPC

Persistence

Messaging/Queues

Reporting/Tracking

–Vaughn Vernon. “Implementing Domain-Driven Design”

“Anything that can help us give more emphasis to the Core Domain and less

to technology will likely drive out

more value for the business and help it achieve an even greater competitive

advantage.”

Detecting when a violation of our promise

occurs

Let’s start

• By building something small

• By building something testable

• By building something easily interchangeable

• With hard boundaries

• With single responsibility everywhere

User In-AppPurchases

Feature Y

Feature X

HTTP Adapter

Acceptance Tests

Game

Analytics

Building something small

User

HTTP Adapter

Acceptance Tests

The secret of building large apps is never build

large apps

Building something testable

User

Acceptance Tests Unit

Tests

In-AppPurchases

Integration Tests

Persistence

HTTP Adapter

FunctionalE2E Tests

Acceptance Tests• It is a validation activity – Did we build the right

thing?

• Can instantiate and exercise the domain model without instantiating any of the technical plumbing that connects it to the external resources in the real system

• Can be described in plain English

Acceptance Tests

• Ports & Adapters makes it possible to run acceptance tests directly against the application domain model

http://www.natpryce.com/articles/000786.html

An acceptance can instantiate and exercise the domain model without instantiating any of the technical plumbing that connects it to the external resources in the real system.

http://www.natpryce.com/articles/000786.html

The opposite: instantiate the adapters without the domain model of the real application. Rather than connecting the adapter to an object from the real domain model, the test connects it to a fake implementation

http://www.natpryce.com/articles/000786.html

By building something easily interchangeable

UserHTTP

Adapter

Acceptance Tests

User

Fake Analytics

With hard boundaries

User In-AppPurchases

Feature Y

Feature X

Game

Analytics

Kernel

Unit Of Work

Event Publisher

HTTP AdapterSilex

Service Locator

HTTP AdapterSymfony

Container Event Dispatcher

LoggerLogger

Tracker

Container

Single Responsibility Everywhere

Are we talking about microservices

No, not yet

• You shouldn't start a new project with microservices, even if you're sure your application will be big enough to make it worthwhile – @martinfowler

• http://martinfowler.com/bliki/MonolithFirst.html

Ports and Adapters• Ports and Adapters is a coarse-grain OO design

pattern

• It decouples the object model of a system's application domain from the object models of its technical domains

• Among other benefits, this lets you write acceptance tests against the application domain model directly

Ports and Adapters

• Says nothing about distribution between processes, machines and/or organizations.

• It's concerned with how we structure our objects within each process

Modules

• Ports&Adapters promotes a loosely coupled architecture, with functionality broken down into independent modules

Implementation

Emerald

• Highly opinionated library following the architectural principles described here

• Not open source yet, but we can see some code later

Principles• Broken down into independent modules

• Modules don’t interact with other modules

• Modules don’t share runtime services (by their self) with other modules

• There is no access to global state, or a global “container” of services

Principles• Modules don’t know anything about the rest of the

world

• They don’t even know that they are running together with other modules

• Modules don’t interact with other modules

• They have very limited knowledge of what’s going on in the rest of the system

Interacting with the rest of the world

• Modules either receive commands or queries from the outside world (adapters)

• This promote CQRS

• Modules publish events, and could react to other events in the system, but without coupling to other modules

The Kernel

User In-AppPurchases

Feature Y

Feature X

Game

AnalyticsKernel

Command

Query

The big picture

User In-AppPurchases

Feature Y

Feature X

Game

AnalyticsKernel

Command

Query

POST /alliance/123

AllianceCreateCmd { id :123, name: “PHP”, }

GET /alliance/123/

AllianceMembersQuery { id :123

Symfony/Silex implementation tips

Controllers• POPOs, only have access to the application Kernel

and have only the following responsibilities:

• convert request in queries or commands

• dispatch control to the kernel

• convert back the response to a suitable representation

Container, Event Dispatcher, etc…

• We need clear separation between all the layer, better to have them separated

• Application has it own service locator and event publisher

Conclusions

• Do not let any (web) framework guide your architecture

• Try to solve your problem first, then chose delivery mechanisms, persistence, etc…

• This kind of architecture can be applied in any programming language/stack

Let’s see some code

References• Hexagonal architecture

http://alistair.cockburn.us/Hexagonal+architecture

• Growing Object-Oriented Software Guided by Testshttp://www.growing-object-oriented-software.com/

• Visualising Test Terminology http://www.natpryce.com/articles/000772.html

• Ports and Adapters With No Domain Modelhttp://www.natpryce.com/articles/000786.html

• http://martinfowler.com/bliki/MonolithFirst.html

Gracias!