SlideShare uma empresa Scribd logo
1 de 95
Baixar para ler offline
Twitter: @matthiasnoback
Matthias Noback
A Series of Fortunate Events
What are events, really?
Things that happen
They trigger actions
Just now...
Attendees arrived,
triggered me to turn on microphone,
which triggered you to stop talking,
which triggered me to start talking
Events in software
Events model what happened in a system
Other parts of the system
can respond to what happened
Imperative programming
Only commands
doThis();
doThat();
updateSomething($something);
return $something;
Extracting events
doThis();
// this was done
doThat();
// that was done
updateSomething($something)
// something was updated
return $something;
Starting position
class PostService
{
...
function addComment($postId, $comment)
{
$post = $this->fetchPost($postId);
$post->addComment($comment);
$this->save($post);
$this->logger->info('New comment');
$this->mailer->send('New comment');
}
}
Starting position
class PostService
{
function __construct(
Mailer $mailer,
Logger $logger
) {
$this->mailer = $mailer;
$this->logger = $logger;
}
function addComment($postId, $comment)
{
...
}
}
Making events explicit
class PostService
{
function addComment($postId, $comment)
{
...
$this->newCommentAdded();
}
function newCommentAdded()
{
$this->logger->info('New comment');
$this->mailer->send('New comment');
}
}
Dependency graph
PostServicePostService
Mailer
Logger
Design issues (1)
I don't think the PostService should
know how to use a Mailer and a Logger
Design issues (2)
I want to change the behavior of
PostService without modifying the
class itself
Fix the problems
By introducing events!
(later)
Observer pattern
Notify other parts of the application
when a change occurs
class PostService
{
function newCommentAdded()
{
foreach ($this->observers as $observer) {
$observer->notify();
}
}
}
Observer contract
interface Observer
{
function notify();
}
Subject knows nothing about its
observers, except their very simple
interface
Concrete observers
class LoggingObserver implements Observer
{
function __construct(Logger $logger)
{
$this->logger = $logger;
}
function notify()
{
$this->logger->info('New comment');
}
}
Concrete observers
class NotificationMailObserver implements Observer
{
function __construct(Mailer $mailer)
{
$this->mailer = $mailer;
}
function notify()
{
$this->mailer->send('New comment');
}
}
Configuration
class PostService
{
function __construct(array $observers)
{
$this->observers = $observers;
}
}
$postService = new PostService(
array(
new LoggingObserver($logger),
new NotificationMailObserver($mailer)
)
);
Before
PostServicePostService
Mailer
Logger
After
NotificationMailObserver
Observer
Observer
LoggingObserver
Mailer
Logger
PostService
Design Principles Party
Single responsibility
Each class has one small,
well-defined responsibility
Single responsibility
● PostService:
“add comments to posts”
● LoggingObserver:
“write a line to the log”
● NotificationMailObserver:
“send a notification mail”
Single responsibility
When a change is required, it can be
isolated to just a small part of the
application
Single responsibility
●
“Capitalize the comment!”:
PostService
●
“Use a different logger!”:
LoggerObserver
●
“Add a timestamp to the notification mail!”:
NotificationMailObserver
Dependency inversion
Depend on abstractions,noton
concretions
Dependency inversion
First PostService depended on
something concrete: the Mailer,the
Logger.
Mailer
LoggerPostService
Dependency inversion
Now it depends on something abstract:
an Observer
Observer
Observer
PostService
Dependency inversion
Only the concrete observers depend on
concrete things like Mailer and Logger
NotificationMailObserver
LoggingObserver
Mailer
Logger
Open/closed
A class should be open for extension and
closed for modification
Open/closed
You don't need to modify the class to
change its behavior
Observer
Observer Observer
PostService
Open/closed
We made it closed for modification,
open for extension
Event data
Mr. Boddy was murdered!
● By Mrs. Peacock
● In the dining room
● With a candle stick
Currently missing!
class LogNewCommentObserver implements Observer
{
function notify()
{
// we'd like to be more specific
$this->logger->info('New comment');
}
}
Event object
class CommentAddedEvent
{
public function __construct($postId, $comment)
{
$this->postId = $postId;
$this->comment = $comment;
}
function comment()
{
return $this->comment;
}
function postId()
{
return $this->postId;
}
}
Event object
We use the event object
to store the context of the event
From observer...
interface Observer
{
function notify();
}
… to event handler
interface CommentAddedEventHandler
{
function handle(CommentAddedEvent $event);
}
Event handlers
class LoggingEventHandler implements
CommentAddedEventHandler
{
function __construct(Logger $logger)
{
$this->logger = $logger;
}
public function handle(CommentAddedEvent $event)
{
$this->logger->info(
'New comment' . $event->comment()
);
}
}
Event handlers
class NotificationMailEventHandler implements
CommentAddedEventHandler
{
function __construct(Mailer $mailer)
{
$this->mailer = $mailer;
}
public function handle(CommentAddedEvent $event)
{
$this->mailer->send(
'New comment: ' . $event->comment();
);
}
}
Configuration
class PostService
{
function __construct(array $eventHandlers)
{
$this->eventHandlers = $eventHandlers;
}
}
$postService = new PostService(
array(
new LoggingEventHandler($logger),
new NotificationMailEventHandler($mailer)
)
);
Looping over event handlers
class PostService
{
public function addComment($postId, $comment)
{
$this->newCommentAdded($postId, $comment);
}
function newCommentAdded($postId, $comment)
{
$event = new CommentAddedEvent(
$postId,
$comment
);
foreach ($this->eventHandlers as $eventHandler) {
$eventHandler->handle($event);
}
}
}
Introducing a Mediator
Instead of talking to the event handlers
Let's leave the talking to a mediator
Mediators for events
●
Doctrine, Zend: Event manager
●
The PHP League: Event emitter
●
Symfony: Event dispatcher
Before
LoggingEventHandler::handle()
NotificationMailEventHandler::handle()
PostService
After
LoggingEventHandler::handle()
NotificationMailEventHandler::handle()
EventDispatcherPostService
In code
class PostService
{
function __construct(EventDispatcherInterface $dispatcher)
{
$this->dispatcher = $dispatcher;
}
function newCommentAdded($postId, $comment)
{
$event = new CommentAddedEvent($postId, $comment);
$this->dispatcher->dispatch(
'comment_added',
$event
);
}
}
Event class
use SymfonyComponentEventDispatcherEvent;
class CommentAddedEvent extends Event
{
...
}
Custom event classes should extend
Symfony Event class:
Configuration
use SymfonyComponentEventDispatcherEvent;
$dispatcher = new EventDispatcher();
$loggingEventHandler = new
LoggingEventHandler($logger);
$dispatcher->addListener(
'comment_added',
array($loggingEventHandler, 'handle')
);
...
$postService = new PostService($dispatcher);
Symfony2
●
An event dispatcher is available as the
event_dispatcher service
●
You can register event listeners using
service tags
Inject the event dispatcher
# services.yml
services:
post_service:
class: PostService
arguments: [@event_dispatcher]
Register your listeners
# services.yml
services:
...
logging_event_handler:
class: LoggingEventHandler
arguments: [@logger]
tags:
- {
name: kernel.event_listener
event: comment_added
method: handle
}
Events and application flow
Symfony2 uses events to generate
response for any given HTTP request
The HttpKernel
$request = Request::createFromGlobals();
// $kernel is in an instance of HttpKernelInterface
$response = $kernel->handle($request);
$response->send();
Kernel events
kernel.request
●
Route matching
●
Authentication
kernel.controller
●
Replace the controller
●
Do some access checks
kernel.response
●
Modify the response
●
E.g. inject the Symfony toolbar
Special types of events
●
Kernel events are not merely
notifications
●
They allow other parts of the
application to step in and modify or
override behavior
Chain of responsibility
Handler 3Handler 1 Handler 2
Some sort
of request
Some sort
of request
Response
Some sort
of request
Symfony example
Listener 3Listener 1 Listener 2
Exception! Exception!
Response
I've got an exception!
What should I tell the user?
Propagation
class HandleExceptionListener
{
function onKernelException(
GetResponseForExceptionEvent $event
) {
$event->setResponse(new Response('Error!'));
// this is the best response ever, don't let
// others spoil it!
$event->stopPropagation();
}
}
Priorities
$dispatcher = new EventDispatcher();
$dispatcher->addListener(
'comment_added',
array($object, $method),
// priority
100
);
Concerns
Concern 1: Hard to understand
“Click-through understanding” impossible
$event = new CommentAddedEvent($postId, $comment);
$this->dispatcher->dispatch(
'comment_added',
$event
);
interface EventDispatcherInterface
{
function dispatch($eventName, Event $event = null);
...
}
Solution
Use Xdebug
Concern 2: Out-of-domain concepts
●
“Comment”
●
“PostId”
●
“Add comment to post”
●
“Dispatcher” (?!)
We did a good thing
We fixed coupling issues
She's called Cohesion
But this guy, Coupling,
has a sister
Cohesion
● Belonging together
● Concepts like “dispatcher”, “event listener”, even
“event”, don't belong in your code
Solutions (1)
Descriptive, explicit naming:
● NotificationMailEventListenerbecomes
SendNotificationMailWhenCommentAdded
● CommentAddedEvent becomes CommentAdded
●
onCommentAdded becomes
whenCommentAdded
Solutions (1)
This also hides implementation details!
Solutions (2)
Use an event dispatcher for things
that are not naturally cohesive anyway
Solutions (2)
Use something else
when an event dispatcher causes low cohesion
Example: resolving the controller
$event = new GetResponseEvent($request);
$dispatcher->dispatch('kernel.request', $event);
$controller = $request->attributes->get('_controller');
$controller = $controllerResolver->resolve($request);
Concern 3: Loss of control
●
You rely on event listeners to do some really
important work
●
How do you know if they are in place
and do their job?
Solution
●
“Won't fix”
●
You have to learn to live with it
It's good
Inversion of control
exercise
control
give up
control!
Just like...
●
A router determines the right controller
●
The service container injects the right
constructor arguments
●
And when you die, someone will bury your
body for you
I admit, inversion of control can be scary
But it will
●
lead to better design
●
require less change
●
make maintenance easier
PresentationFinished
AskQuestionsWhenPresentationFinished
SayThankYouWhenNoMoreQuestions
Class and package design principles
http://leanpub.com/principles-of-package-design/c/phpbnl15
Get it for $ 19
Design patterns
●
Observer
●
Mediator
●
Chain of responsibility
●
...
Design Patterns by “The Gang of Four”
SOLID principles
●
Single responsibility
●
Open/closed
●
Dependency inversion
●
...
Agile Software Development by Robert C. Martin
Images
●
www.ohiseered.com/2011_11_01_archive.html
●
Mrs. Peacock, Candlestick:
www.cluecult.com
●
Leonardo DiCaprio:
screenrant.com/leonardo-dicaprio-defends-wolf-wall-street-controversy/
●
Book covers:
Amazon
●
Party:
todesignoffsite.com/events-2/to-do-closing-party-with-love-design/
●
Russell Crowe:
malinaelena.wordpress.com/2014/04/18/top-8-filme-cu-russell-crowe/
Twitter: @matthiasnoback
joind.in/13120
What did you think?

Mais conteúdo relacionado

Mais procurados

iOS Memory Management Basics
iOS Memory Management BasicsiOS Memory Management Basics
iOS Memory Management BasicsBilue
 
The combine triad
The combine triadThe combine triad
The combine triadDonny Wals
 
Reactive.architecture.with.Angular
Reactive.architecture.with.AngularReactive.architecture.with.Angular
Reactive.architecture.with.AngularEvan Schultz
 
Memory management in Objective C
Memory management in Objective CMemory management in Objective C
Memory management in Objective CNeha Gupta
 
Learn You a ReactiveCocoa for Great Good
Learn You a ReactiveCocoa for Great GoodLearn You a ReactiveCocoa for Great Good
Learn You a ReactiveCocoa for Great GoodJason Larsen
 
Akka: Actor Design & Communication Technics
Akka: Actor Design & Communication TechnicsAkka: Actor Design & Communication Technics
Akka: Actor Design & Communication TechnicsAlex Fruzenshtein
 
$q and Promises in AngularJS
$q and Promises in AngularJS $q and Promises in AngularJS
$q and Promises in AngularJS a_sharif
 
Taming Core Data by Arek Holko, Macoscope
Taming Core Data by Arek Holko, MacoscopeTaming Core Data by Arek Holko, Macoscope
Taming Core Data by Arek Holko, MacoscopeMacoscope
 
Symfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worldsSymfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worldsIgnacio Martín
 
JavaScript promise
JavaScript promiseJavaScript promise
JavaScript promiseeslam_me
 
Guard Authentication: Powerful, Beautiful Security
Guard Authentication: Powerful, Beautiful SecurityGuard Authentication: Powerful, Beautiful Security
Guard Authentication: Powerful, Beautiful SecurityRyan Weaver
 
Advanced Memory Management on iOS and Android - Mark Probst and Rodrigo Kumpera
Advanced Memory Management on iOS and Android - Mark Probst and Rodrigo KumperaAdvanced Memory Management on iOS and Android - Mark Probst and Rodrigo Kumpera
Advanced Memory Management on iOS and Android - Mark Probst and Rodrigo KumperaXamarin
 
Design how your objects talk through mocking
Design how your objects talk through mockingDesign how your objects talk through mocking
Design how your objects talk through mockingKonstantin Kudryashov
 
Understanding react hooks
Understanding react hooksUnderstanding react hooks
Understanding react hooksSamundra khatri
 

Mais procurados (20)

Rxjs swetugg
Rxjs swetuggRxjs swetugg
Rxjs swetugg
 
iOS Memory Management Basics
iOS Memory Management BasicsiOS Memory Management Basics
iOS Memory Management Basics
 
The combine triad
The combine triadThe combine triad
The combine triad
 
Reactive.architecture.with.Angular
Reactive.architecture.with.AngularReactive.architecture.with.Angular
Reactive.architecture.with.Angular
 
Rxjs ngvikings
Rxjs ngvikingsRxjs ngvikings
Rxjs ngvikings
 
Memory management in Objective C
Memory management in Objective CMemory management in Objective C
Memory management in Objective C
 
Learn You a ReactiveCocoa for Great Good
Learn You a ReactiveCocoa for Great GoodLearn You a ReactiveCocoa for Great Good
Learn You a ReactiveCocoa for Great Good
 
Akka: Actor Design & Communication Technics
Akka: Actor Design & Communication TechnicsAkka: Actor Design & Communication Technics
Akka: Actor Design & Communication Technics
 
Objective C Memory Management
Objective C Memory ManagementObjective C Memory Management
Objective C Memory Management
 
$q and Promises in AngularJS
$q and Promises in AngularJS $q and Promises in AngularJS
$q and Promises in AngularJS
 
React hooks
React hooksReact hooks
React hooks
 
Taming Core Data by Arek Holko, Macoscope
Taming Core Data by Arek Holko, MacoscopeTaming Core Data by Arek Holko, Macoscope
Taming Core Data by Arek Holko, Macoscope
 
Symfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worldsSymfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worlds
 
JavaScript promise
JavaScript promiseJavaScript promise
JavaScript promise
 
Guard Authentication: Powerful, Beautiful Security
Guard Authentication: Powerful, Beautiful SecurityGuard Authentication: Powerful, Beautiful Security
Guard Authentication: Powerful, Beautiful Security
 
Advanced Memory Management on iOS and Android - Mark Probst and Rodrigo Kumpera
Advanced Memory Management on iOS and Android - Mark Probst and Rodrigo KumperaAdvanced Memory Management on iOS and Android - Mark Probst and Rodrigo Kumpera
Advanced Memory Management on iOS and Android - Mark Probst and Rodrigo Kumpera
 
Design how your objects talk through mocking
Design how your objects talk through mockingDesign how your objects talk through mocking
Design how your objects talk through mocking
 
Rxjs vienna
Rxjs viennaRxjs vienna
Rxjs vienna
 
Bot builder v4 HOL
Bot builder v4 HOLBot builder v4 HOL
Bot builder v4 HOL
 
Understanding react hooks
Understanding react hooksUnderstanding react hooks
Understanding react hooks
 

Semelhante a A Series of Fortunate Events - PHP Benelux Conference 2015

A Series of Fortunate Events - Drupalcon Europe, Amsterdam 2014
A Series of Fortunate Events - Drupalcon Europe, Amsterdam 2014A Series of Fortunate Events - Drupalcon Europe, Amsterdam 2014
A Series of Fortunate Events - Drupalcon Europe, Amsterdam 2014Matthias Noback
 
A Series of Fortunate Events - Symfony Camp Sweden 2014
A Series of Fortunate Events - Symfony Camp Sweden 2014A Series of Fortunate Events - Symfony Camp Sweden 2014
A Series of Fortunate Events - Symfony Camp Sweden 2014Matthias Noback
 
EventBus for Android
EventBus for AndroidEventBus for Android
EventBus for Androidgreenrobot
 
Dependency Injection in Drupal 8
Dependency Injection in Drupal 8Dependency Injection in Drupal 8
Dependency Injection in Drupal 8katbailey
 
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STMConcurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STMMario Fusco
 
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
 
Inversion Of Control
Inversion Of ControlInversion Of Control
Inversion Of ControlChad Hietala
 
The state of hooking into Drupal - DrupalCon Dublin
The state of hooking into Drupal - DrupalCon DublinThe state of hooking into Drupal - DrupalCon Dublin
The state of hooking into Drupal - DrupalCon DublinNida Ismail Shah
 
Symfony2 from the Trenches
Symfony2 from the TrenchesSymfony2 from the Trenches
Symfony2 from the TrenchesJonathan Wage
 
Symfony2 - from the trenches
Symfony2 - from the trenchesSymfony2 - from the trenches
Symfony2 - from the trenchesLukas Smith
 
Advanced #3 threading
Advanced #3  threading Advanced #3  threading
Advanced #3 threading Vitali Pekelis
 
Photon Server Deep Dive - View from Implmentation of PhotonWire, Multiplayer ...
Photon Server Deep Dive - View from Implmentation of PhotonWire, Multiplayer ...Photon Server Deep Dive - View from Implmentation of PhotonWire, Multiplayer ...
Photon Server Deep Dive - View from Implmentation of PhotonWire, Multiplayer ...Yoshifumi Kawai
 
Implementações paralelas
Implementações paralelasImplementações paralelas
Implementações paralelasWillian Molinari
 
Task scheduling in laravel 8 tutorial
Task scheduling in laravel 8 tutorialTask scheduling in laravel 8 tutorial
Task scheduling in laravel 8 tutorialKaty Slemon
 
Declarative presentations UIKonf
Declarative presentations UIKonfDeclarative presentations UIKonf
Declarative presentations UIKonfNataliya Patsovska
 
Architecture your android_application
Architecture your android_applicationArchitecture your android_application
Architecture your android_applicationMark Brady
 
Mastering the Lightning Framework - Part 2
Mastering the Lightning Framework - Part 2Mastering the Lightning Framework - Part 2
Mastering the Lightning Framework - Part 2Salesforce Developers
 

Semelhante a A Series of Fortunate Events - PHP Benelux Conference 2015 (20)

A Series of Fortunate Events - Drupalcon Europe, Amsterdam 2014
A Series of Fortunate Events - Drupalcon Europe, Amsterdam 2014A Series of Fortunate Events - Drupalcon Europe, Amsterdam 2014
A Series of Fortunate Events - Drupalcon Europe, Amsterdam 2014
 
A Series of Fortunate Events - Symfony Camp Sweden 2014
A Series of Fortunate Events - Symfony Camp Sweden 2014A Series of Fortunate Events - Symfony Camp Sweden 2014
A Series of Fortunate Events - Symfony Camp Sweden 2014
 
Event Driven Applications in F#
Event Driven Applications in F#Event Driven Applications in F#
Event Driven Applications in F#
 
EventBus for Android
EventBus for AndroidEventBus for Android
EventBus for Android
 
Dependency Injection in Drupal 8
Dependency Injection in Drupal 8Dependency Injection in Drupal 8
Dependency Injection in Drupal 8
 
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STMConcurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
Concurrency, Scalability & Fault-tolerance 2.0 with Akka Actors & STM
 
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
 
Inversion Of Control
Inversion Of ControlInversion Of Control
Inversion Of Control
 
The state of hooking into Drupal - DrupalCon Dublin
The state of hooking into Drupal - DrupalCon DublinThe state of hooking into Drupal - DrupalCon Dublin
The state of hooking into Drupal - DrupalCon Dublin
 
Symfony2 from the Trenches
Symfony2 from the TrenchesSymfony2 from the Trenches
Symfony2 from the Trenches
 
Symfony2 - from the trenches
Symfony2 - from the trenchesSymfony2 - from the trenches
Symfony2 - from the trenches
 
Advanced #3 threading
Advanced #3  threading Advanced #3  threading
Advanced #3 threading
 
Ext Js Events
Ext Js EventsExt Js Events
Ext Js Events
 
Ext Js Events
Ext Js EventsExt Js Events
Ext Js Events
 
Photon Server Deep Dive - View from Implmentation of PhotonWire, Multiplayer ...
Photon Server Deep Dive - View from Implmentation of PhotonWire, Multiplayer ...Photon Server Deep Dive - View from Implmentation of PhotonWire, Multiplayer ...
Photon Server Deep Dive - View from Implmentation of PhotonWire, Multiplayer ...
 
Implementações paralelas
Implementações paralelasImplementações paralelas
Implementações paralelas
 
Task scheduling in laravel 8 tutorial
Task scheduling in laravel 8 tutorialTask scheduling in laravel 8 tutorial
Task scheduling in laravel 8 tutorial
 
Declarative presentations UIKonf
Declarative presentations UIKonfDeclarative presentations UIKonf
Declarative presentations UIKonf
 
Architecture your android_application
Architecture your android_applicationArchitecture your android_application
Architecture your android_application
 
Mastering the Lightning Framework - Part 2
Mastering the Lightning Framework - Part 2Mastering the Lightning Framework - Part 2
Mastering the Lightning Framework - Part 2
 

Mais de Matthias Noback

Rector fireside chat - PHPMiNDS meetup
Rector fireside chat - PHPMiNDS meetupRector fireside chat - PHPMiNDS meetup
Rector fireside chat - PHPMiNDS meetupMatthias Noback
 
Service abstractions - Part 1: Queries
Service abstractions - Part 1: QueriesService abstractions - Part 1: Queries
Service abstractions - Part 1: QueriesMatthias Noback
 
Hexagonal Symfony - SymfonyCon Amsterdam 2019
Hexagonal Symfony - SymfonyCon Amsterdam 2019Hexagonal Symfony - SymfonyCon Amsterdam 2019
Hexagonal Symfony - SymfonyCon Amsterdam 2019Matthias Noback
 
Advanced web application architecture - PHP Barcelona
Advanced web application architecture  - PHP BarcelonaAdvanced web application architecture  - PHP Barcelona
Advanced web application architecture - PHP BarcelonaMatthias Noback
 
A testing strategy for hexagonal applications
A testing strategy for hexagonal applicationsA testing strategy for hexagonal applications
A testing strategy for hexagonal applicationsMatthias Noback
 
Advanced web application architecture - Talk
Advanced web application architecture - TalkAdvanced web application architecture - Talk
Advanced web application architecture - TalkMatthias Noback
 
DPC 2019, Amsterdam: Beyond design patterns and principles - writing good OO ...
DPC 2019, Amsterdam: Beyond design patterns and principles - writing good OO ...DPC 2019, Amsterdam: Beyond design patterns and principles - writing good OO ...
DPC 2019, Amsterdam: Beyond design patterns and principles - writing good OO ...Matthias Noback
 
Layers, ports and adapters
Layers, ports and adaptersLayers, ports and adapters
Layers, ports and adaptersMatthias Noback
 
Beyond design principles and patterns (muCon 2019 edition)
Beyond design principles and patterns (muCon 2019 edition)Beyond design principles and patterns (muCon 2019 edition)
Beyond design principles and patterns (muCon 2019 edition)Matthias Noback
 
Brutal refactoring, lying code, the Churn, and other emotional stories from L...
Brutal refactoring, lying code, the Churn, and other emotional stories from L...Brutal refactoring, lying code, the Churn, and other emotional stories from L...
Brutal refactoring, lying code, the Churn, and other emotional stories from L...Matthias Noback
 
Advanced web application architecture Way2Web
Advanced web application architecture Way2WebAdvanced web application architecture Way2Web
Advanced web application architecture Way2WebMatthias Noback
 
Brutal refactoring, lying code, the Churn, and other emotional stories from L...
Brutal refactoring, lying code, the Churn, and other emotional stories from L...Brutal refactoring, lying code, the Churn, and other emotional stories from L...
Brutal refactoring, lying code, the Churn, and other emotional stories from L...Matthias Noback
 
Beyond Design Principles and Patterns
Beyond Design Principles and PatternsBeyond Design Principles and Patterns
Beyond Design Principles and PatternsMatthias Noback
 
Building Autonomous Services
Building Autonomous ServicesBuilding Autonomous Services
Building Autonomous ServicesMatthias Noback
 
Advanced Application Architecture Symfony Live Berlin 2018
Advanced Application Architecture Symfony Live Berlin 2018Advanced Application Architecture Symfony Live Berlin 2018
Advanced Application Architecture Symfony Live Berlin 2018Matthias Noback
 
Building autonomous services
Building autonomous servicesBuilding autonomous services
Building autonomous servicesMatthias Noback
 

Mais de Matthias Noback (20)

Rector fireside chat - PHPMiNDS meetup
Rector fireside chat - PHPMiNDS meetupRector fireside chat - PHPMiNDS meetup
Rector fireside chat - PHPMiNDS meetup
 
Service abstractions - Part 1: Queries
Service abstractions - Part 1: QueriesService abstractions - Part 1: Queries
Service abstractions - Part 1: Queries
 
Hexagonal Symfony - SymfonyCon Amsterdam 2019
Hexagonal Symfony - SymfonyCon Amsterdam 2019Hexagonal Symfony - SymfonyCon Amsterdam 2019
Hexagonal Symfony - SymfonyCon Amsterdam 2019
 
Advanced web application architecture - PHP Barcelona
Advanced web application architecture  - PHP BarcelonaAdvanced web application architecture  - PHP Barcelona
Advanced web application architecture - PHP Barcelona
 
A testing strategy for hexagonal applications
A testing strategy for hexagonal applicationsA testing strategy for hexagonal applications
A testing strategy for hexagonal applications
 
Advanced web application architecture - Talk
Advanced web application architecture - TalkAdvanced web application architecture - Talk
Advanced web application architecture - Talk
 
DPC 2019, Amsterdam: Beyond design patterns and principles - writing good OO ...
DPC 2019, Amsterdam: Beyond design patterns and principles - writing good OO ...DPC 2019, Amsterdam: Beyond design patterns and principles - writing good OO ...
DPC 2019, Amsterdam: Beyond design patterns and principles - writing good OO ...
 
Layers, ports and adapters
Layers, ports and adaptersLayers, ports and adapters
Layers, ports and adapters
 
Beyond design principles and patterns (muCon 2019 edition)
Beyond design principles and patterns (muCon 2019 edition)Beyond design principles and patterns (muCon 2019 edition)
Beyond design principles and patterns (muCon 2019 edition)
 
Brutal refactoring, lying code, the Churn, and other emotional stories from L...
Brutal refactoring, lying code, the Churn, and other emotional stories from L...Brutal refactoring, lying code, the Churn, and other emotional stories from L...
Brutal refactoring, lying code, the Churn, and other emotional stories from L...
 
Advanced web application architecture Way2Web
Advanced web application architecture Way2WebAdvanced web application architecture Way2Web
Advanced web application architecture Way2Web
 
Brutal refactoring, lying code, the Churn, and other emotional stories from L...
Brutal refactoring, lying code, the Churn, and other emotional stories from L...Brutal refactoring, lying code, the Churn, and other emotional stories from L...
Brutal refactoring, lying code, the Churn, and other emotional stories from L...
 
Beyond Design Principles and Patterns
Beyond Design Principles and PatternsBeyond Design Principles and Patterns
Beyond Design Principles and Patterns
 
Building Autonomous Services
Building Autonomous ServicesBuilding Autonomous Services
Building Autonomous Services
 
Advanced Application Architecture Symfony Live Berlin 2018
Advanced Application Architecture Symfony Live Berlin 2018Advanced Application Architecture Symfony Live Berlin 2018
Advanced Application Architecture Symfony Live Berlin 2018
 
Designing for Autonomy
Designing for AutonomyDesigning for Autonomy
Designing for Autonomy
 
Docker workshop
Docker workshopDocker workshop
Docker workshop
 
Docker swarm workshop
Docker swarm workshopDocker swarm workshop
Docker swarm workshop
 
Docker compose workshop
Docker compose workshopDocker compose workshop
Docker compose workshop
 
Building autonomous services
Building autonomous servicesBuilding autonomous services
Building autonomous services
 

Último

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
 
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
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Servicegiselly40
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEarley Information Science
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024The Digital Insurer
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slidevu2urc
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 

Último (20)

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
 
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
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 

A Series of Fortunate Events - PHP Benelux Conference 2015