+ All Categories
Home > Software > Hexagonal architecture - message-oriented software design

Hexagonal architecture - message-oriented software design

Date post: 03-Aug-2015
Category:
Upload: matthiasnoback
View: 929 times
Download: 5 times
Share this document with a friend
73
HEXAGONAL ARCHITECTURE Message oriented software design By Matthias Noback
Transcript
Page 1: Hexagonal architecture  - message-oriented software design

HEXAGONAL ARCHITECTURE Message oriented software design

By Matthias Noback

Page 2: Hexagonal architecture  - message-oriented software design

ARCHITECTUREWhat's the problem?

Page 3: Hexagonal architecture  - message-oriented software design

!!!

Nice app

Page 4: Hexagonal architecture  - message-oriented software design

!!!

Sad app

Page 5: Hexagonal architecture  - message-oriented software design

Your brain can't handle it

M V C ?

Page 6: Hexagonal architecture  - message-oriented software design

Coupling with frameworks and libraries

!!!

Page 7: Hexagonal architecture  - message-oriented software design

How do you start a new project?

Pick a framework

Install a skeleton project

Remove demo stuff

Auto-generate a CRUD controller

Auto-generate an entity

Done

"It's a Symfony project!"

Page 8: Hexagonal architecture  - message-oriented software design

That's actually outside inThe boring stuff

The interesting stuff

Page 9: Hexagonal architecture  - message-oriented software design

Slow tests

DB

Browser

Message queue

Key-value

Page 10: Hexagonal architecture  - message-oriented software design

Frameworks taught us about encapsulation

Page 11: Hexagonal architecture  - message-oriented software design

Low-level API

$requestContent = file_get_contents('php://input'); $contentType = $_SERVER['CONTENT_TYPE']; if ($contentType === 'application/json') { $data = json_decode($requestContent, true); } elseif ($contentType === 'application/xml') { $xml = simplexml_load_string($requestContent); ... }

Page 12: Hexagonal architecture  - message-oriented software design

Nicely hides the details

$data = $serializer->deserialize( $request->getContent(), $request->getContentType() );

Page 13: Hexagonal architecture  - message-oriented software design

Low-level API

$stmt = $db->prepare( 'SELECT * FROM Patient p WHERE p.anonymous = ?' ); $stmt->bindValue(1, true); $stmt->execute(); $result = $stmt->fetch(\PDO::FETCH_ASSOC); $patient = Patient::reconstituteFromArray($result);

Page 14: Hexagonal architecture  - message-oriented software design

Hides a lot of details

$patient = $repository->createQueryBuilder('p') ->where('p.anonymous = true') ->getQuery() ->getResult();

Page 15: Hexagonal architecture  - message-oriented software design

What about abstraction?

Page 16: Hexagonal architecture  - message-oriented software design

$patient = $repository->createQueryBuilder('p') ->where('p.anonymous = true') ->getQuery() ->getResult();

Concrete

Concrete

Concrete

Page 17: Hexagonal architecture  - message-oriented software design

$patients = $repository->anonymousPatients();

Abstract

Nice

Page 18: Hexagonal architecture  - message-oriented software design

Coupling to the delivery mechanism

Page 19: Hexagonal architecture  - message-oriented software design

public function registerPatientAction(Request $request) { $patient = new Patient(); ! $form = $this->createForm(new RegisterPatientForm(), $patient); ! $form->handleRequest($request); ! if ($form->isValid()) { $em = $this->getDoctrine()->getManager(); $em->persist($patient); $em->flush(); ! return $this->redirect($this->generateUrl('patient_list')); } ! return array( 'form' => $form->createView() ); }

Request and Form are web-specific

EntityManager is ORM, i.e. relational DB-specific

Page 20: Hexagonal architecture  - message-oriented software design

Reusability: impossible

Page 21: Hexagonal architecture  - message-oriented software design

Some functionality

The web

The CLI

Page 22: Hexagonal architecture  - message-oriented software design

Some functionality

Run it

Page 23: Hexagonal architecture  - message-oriented software design

Lack of intention-revealing code

Page 24: Hexagonal architecture  - message-oriented software design

data

data

data

why?

why?

why?

Page 25: Hexagonal architecture  - message-oriented software design

public function updateAction(Request $request) { $patient = new Patient(); ! $form = $this->createForm(new PatientType(), $patient); ! $form->handleRequest($request); ! if ($form->isValid()) { $em = $this->getDoctrine()->getManager(); $em->persist($patient); $em->flush(); ! return $this->redirect($this->generateUrl('patient_list')); } ! return array( 'form' => $form->createView() ); }

from the HTTP request

copied into an entity

then stored in the database

What exactly changed?!

And... why?

Page 26: Hexagonal architecture  - message-oriented software design

R.A.D.

Rapid Application Development

B.A.D.

B.A.D. Application Development

Page 27: Hexagonal architecture  - message-oriented software design

InconsistenciesGET /balance/ { "currency": "USD", "amount" 20 }

PUT /balance/ { "currency": "EUR", } !

Page 28: Hexagonal architecture  - message-oriented software design

Lack of maintainability

Page 29: Hexagonal architecture  - message-oriented software design

It's hard to find out what happens where

UserController"ProductController"CommentController"CategoryController"AccountController"ProfileController"..."

Page 30: Hexagonal architecture  - message-oriented software design

Web controllers are not the only actions

Page 31: Hexagonal architecture  - message-oriented software design

In summary

Coupling with a framework

Coupling with a delivery mechanism (e.g. the web)

Slow tests

Lack of intention in the code

Page 32: Hexagonal architecture  - message-oriented software design

THE ESSENCEof your application

Page 33: Hexagonal architecture  - message-oriented software design

The essence

Other things

Page 34: Hexagonal architecture  - message-oriented software design

The "heart"?

Page 35: Hexagonal architecture  - message-oriented software design

"The heart of software is its ability to solve domain-related problems for its users.

–Eric Evans, Domain Driven Design

All other features, vital though they may be, support this basic purpose."

Page 36: Hexagonal architecture  - message-oriented software design

What's essential?

Domain model

Interaction with it

Use cases

Page 37: Hexagonal architecture  - message-oriented software design

What's not essential?

Page 38: Hexagonal architecture  - message-oriented software design

“The database is an implementation detail”

–Cool software architect

Page 39: Hexagonal architecture  - message-oriented software design

The core doesn't need to know about it

!!!

Page 40: Hexagonal architecture  - message-oriented software design

!!!

What about interaction?

!

Page 41: Hexagonal architecture  - message-oriented software design

The core doesn't need to know about it

!!!

Page 42: Hexagonal architecture  - message-oriented software design

Infrastructure

The world outside

!!!

Web browser

Terminal

Database

Messaging

Page 43: Hexagonal architecture  - message-oriented software design

Mmm... layers Layers allow you to

separate

Layers allow you to

allocate

Layers have

boundaries

Rules for crossing

Page 44: Hexagonal architecture  - message-oriented software design

Rules about communication

Actually: rules about dependencies

Page 45: Hexagonal architecture  - message-oriented software design

What crosses layer boundaries?

Message

Page 46: Hexagonal architecture  - message-oriented software design

MessagessomeFunctionCall( $arguments, $prepared, $for, $the, $receiver );

$command = new TypeOfMessage( $values, $for, $this, $message ); handle($command);

Page 47: Hexagonal architecture  - message-oriented software design

What about the application boundary?

The app

Messag

e

The world outside

Page 48: Hexagonal architecture  - message-oriented software design

How does an app allow incoming messages at all?

By exposing input ports

Routes Console commands

REST endpoints A WSDL file for a SOAP API

Page 49: Hexagonal architecture  - message-oriented software design
Page 50: Hexagonal architecture  - message-oriented software design
Page 51: Hexagonal architecture  - message-oriented software design

Ports use protocols for communication

Each port has a language of its own

Page 52: Hexagonal architecture  - message-oriented software design

Web (HTTP)

CLI (SAPI, STDIN, etc.)

Page 53: Hexagonal architecture  - message-oriented software design

HTTP Request

Form

Request

Controller

Entity

Value object

Web p

ort

Tran

slate

the re

quest

Repository

Page 54: Hexagonal architecture  - message-oriented software design

Adapters

The translators are called: adapters

Page 55: Hexagonal architecture  - message-oriented software design

"Ports and adapters"

Ports: allow for communication to happen

Adapters: translate messages from the world outside

== Hexagonal architecture

Page 56: Hexagonal architecture  - message-oriented software design

An example

Plain HTTP message

Request object

POST /users/ HTTP/1.1 Host: phpconference.nl !name=Matthias&[email protected]

Command

$command = new RegisterUser( $request->get('name'), $request->get('email') );

Page 57: Hexagonal architecture  - message-oriented software design

Command

$command = new RegisterUser( $request->get('name'), $request->get('email') );

Expresses intention

Implies changeStand-alone

Only the message

Page 58: Hexagonal architecture  - message-oriented software design

class RegisterUserHandler { public function handle(RegisterUser $command) { $user = User::register( $command->name(), $command->email() ); $this->userRepository->add($user); } }

CommandCommand handler

Page 59: Hexagonal architecture  - message-oriented software design

CommandCommand handler A

Command bus

Command handler B

Command handler C

Page 60: Hexagonal architecture  - message-oriented software design

Change

New entity (User)

Calculate changes (UoW)

$user = User::register( $command->name(), $command->email() ); $this->userRepository ->add($user);

Insert query (SQL)

INSERT INTO users SET name='Matthias', email='[email protected]';

Page 61: Hexagonal architecture  - message-oriented software design

SQL query

EntityManager

UnitOfWork

QueryBuilder

Persi

stenc

e port

Prepare

for p

ersist

ence

Repository

Value object

Entity

Page 62: Hexagonal architecture  - message-oriented software design
Page 63: Hexagonal architecture  - message-oriented software design

Messaging (AMQP)

Persistence (MySQL)

Page 64: Hexagonal architecture  - message-oriented software design

UserRepository (uses MySQL)

RegisterUserHandler

Page 65: Hexagonal architecture  - message-oriented software design

MySQL- UserRepository

RegisterUserHandler

Dependency inversion

UserRepository interface

Page 66: Hexagonal architecture  - message-oriented software design

MySQL- UserRepository

RegisterUserHandler

UserRepository interface

InMemory- UserRepository

Speedy alternative

Page 67: Hexagonal architecture  - message-oriented software design

"A good software architecture allows decisions [...] to be deferred and delayed."

–Robert Martin, Screaming Architecture

Page 68: Hexagonal architecture  - message-oriented software design

IN CONCLUSIONwhat did we get from all of this?

Page 69: Hexagonal architecture  - message-oriented software design

Separation of concerns

Core

Infrastructure

Page 70: Hexagonal architecture  - message-oriented software design

CommandCommand

Command handler

Command handler

Stand-alone use cases

Command

Command handler

Intention-revealing

Reusable

Page 71: Hexagonal architecture  - message-oriented software design

Infrastructure stand-ins

Regular implementation

Interface

Stand-in, fast implementation

Page 72: Hexagonal architecture  - message-oriented software design

This is all very much supportive of...

See also: Modelling by Example

DDD

TDDBDD

CQRS

Page 73: Hexagonal architecture  - message-oriented software design

QUESTIONS? FEEDBACK?joind.in/14238


Recommended