Domain Driven Development applied

Post on 29-Jan-2018

222 views 3 download

Transcript of Domain Driven Development applied

(println "Hello World! :)")

DDD as an implementation detail

Eloi PochSergi González

Who$are$we?$$

!es.linkedin.com/in/eloipoch/$

$

$@eloipoch$

$Eloi.poch@akamon.com$

Eloi!Poch!!Technical!Lead!at!@Akamon!•  So8ware$Developer$•  Clojure$developer$wannabe$•  Want$to$code$in$Castefa$beach$while$drinking$wine$

(conj '(1 2 3) 4)

Who$are$we?$$

!es.linkedin.com/in/sergigp/$

$

$“SergiGP$

$Sergi.gonzalez@akamon.com$

Sergi!!Technical!Lead!at!@Akamon!•  So<ware$Developer$•  Chief$Trolling$Officer$•  Two$animals$remaining$to$have$an$urban$zoo$

Akamon

A little bit on Akamon before we deal with the technical stuff

We#develop#Social#Casino#Games#

Por$olio'of'Facebook'games'

Por$olio'of'Mobile'apps'

Recently(launched(a(new(Casino(Suite(

Technically …

Flash Client Game Server Backend

AS3 Nova

Java JReactive & Vertx

PHP Horus

@eloipoch @jordillonch @SergiGP

@jorgeavila_ss @jdiezc @jvalduvieco @amassa5

Who we are? The backend team

Development Problems

Our expectations…

PerformanceBig DataDifficult AlgorithmsConcurrencyReal time analyticsScalability

The ugly truth…

Technical Problems

Code ComplexityBig ball of mudShared StateCoupling

& Non-Technical problems

Different Cultures

Tackling Complex CodeThe Philosophy

Simple made Easy

Complex((

One(role(

One(task(

not(a(single(opera2on(

(

OBJECTIVE

Hard(

Familiar,(near(your(

knowledge(

(

(

Simple(vs(Easy((

SUBJECTIVEOBJECTIVE

Simple vs Easy

$mysqli = new mysqli("localhost", "horus", "olakease", “suite"); $mysqli->query("INSERT INTO users …”))

SIMPLE

EASY

/** * @ORM\Entity * @ORM\Table(name="product") */ class Product

$sum = function ($carry, $item) { return $carry + $item; } array_reduce([1, 2, 3], $sum);

$acc = 0; foreach ([1, 2, 3] as $value) {

$acc += $value; }

SIMPLE

EASY

(reduce + [1 2 3])

Simple vs EasySimple vs Easy

Simplicity vs Easiness

• Easy to understand

• Easy to debug

• Easy to change, flexibility, maintenable

• Easy to use

• Hard to debug

• Hard to change

Complected

• Something does more than one thing and you can’t split it easily

• Source of accidental complexity

• DON’T DO IT

Essential ComplexityVS

Accidental Complexity

Do not complect, compose

Tackling Complex Code

The Theory

Organisational level

Pair Programming

Pull Requests

Code Reviews

Continuous Integration

Self Empowerment

Never ask for permission unless it

would be reckless not to

Trust

Great teams are unafraid to air their dirty laundry, admit their mistakes, their weaknesses and their concerns

without fear. Patrick Lencioni

Technical Level

Lean Approach

Any model/solution is provisional

YAGNIYou Aren’t Gonna Need It

DDD Concepts

• DDD Tactical:

• Application Services

• Domain Services

• Domain Events

• Repositories

• AR & VO

• DDD Strategical:

• Modules

• Bounded Contexts

• SubDomains

• Context Maps

CQRS Concepts

Hexagonal Architecture

TDD & BDD

Tackling Complex Code

The Practice

Divide, Test & Conquer

Product Entity Example

ProductId

NameDescription

PriceCurrencyImage Url

CoinsStoreId

Product

Product Descriptions

Product Prices

Stores

Product Benefits

Product Images

ProductId

Product Description

Product Price

Stores

Product Benefit

Product Image

DescriptionName Currency

Amount

CoinsStoreId

Image Url

ProductId

Product Description

Product Price

Stores

Product Benefit

Product Image

DescriptionName Currency

Amount

CoinsStoreId

Image Url

Product BC

ProductId

Product Description

Product Price

Stores

Product Benefit

Product Image

DescriptionName Currency

Amount

CoinsStoreId

Image Url

Pricing/Sales BC

Product BC

Product

Id

BenefitId

Product Price

ProductId

Amount

Currency

Product Description

ProductId

Name

Description

Product Benefit

Id

Amount

VirtualMoneyId

Product Store

ProductId

StoreId

HORUS

Big Picture

• Directories: 773

• Files: 1501

• Lines of code: 113885

• Non-Comment Lines of Code: 88806 (80%)

• Average Class Length: 14 lines

• Average Method Length: 2 lines

• Cyclomatic Complexity / LLOC: 0.06

• Cyclomatic Complexity / Number of Methods: 1.21

HORUS

Big Picture of our Code in Horus

• Directories: 773 / 558

• Files: 1501 / 1001

• Lines of code: 113885 / 41205

• Non-Comment Lines of Code: 88806 (80%) / 38045 (92%)

• Average Class Length: 14 lines / 5 lines

• Average Method Length: 2 lines / 2 lines

• Cyclomatic Complexity / LLOC: 0.06 / 0.03

• Cyclomatic Complexity / Number of Methods: 1.21 / 1.14

UserPostController Command Bus

UserRegistratorCommandHandler

UserRegistratorDomain Event

Publisher

UserRegisteredDomainEventSubscriber

UserAccountOpener

User UserRepository Event Subscribers

.

.

.

POST /users[

userId: 0db90987-5ce1-4683-bb05-7d1b5539cb0b]

Command Handlers

.

.

.

UserR

egisteredDom

ainEvent

User

HORUS

BASIC REQUEST

UserRegistrationCommand

UserRegistrationCommand

userIdanalyticsContextId

userIdanalyticsContextId

UserRegisteredDomainEvent

userId

analyticsContextId

id (Economy Account)

UserPostController Command Bus

UserRegistratorCommandHandler

UserRegistratorDomain Event

Publisher

UserRegisteredDomainEventSubscriber

UserAccountOpener

User UserRepository Event Subscribers

.

.

.

POST /users[

userId: 0db90987-5ce1-4683-bb05-7d1b5539cb0b]

Command Handlers

.

.

.

UserR

egisteredDom

ainEvent

User

HORUS

BASIC REQUEST

UserRegistrationCommand

UserRegistrationCommand

userIdanalyticsContextId

userIdanalyticsContextId

UserRegisteredDomainEvent

userId

analyticsContextId

id (Economy Account)

UserModule

EconomyModule

Operational

Analytics

Support

Marketing

DE

C

Q

Q

We are still COUPLED !!

Operational

Analytics

Support

Marketing

HTTP

Tackling Complex Code

The Conclusions

Mistakes

• Do not store domain events

• Own libraries for CQRS & DDD

• Do not use Domain Services

• Domain events with wrong identifiers

• Couple App Services to Commands & Queries

• Not start earlier some Modules/Bounded Contexts

Mistakes

• Let the DB guide us

• Let the framework guide us

Problems

• Domain Events: Lost of order (async)

• Doctrine

• Unit Of Work + Integration Test = Fail

• Embedded: Identifier or not

• Behat: The Container

Tips & Tricks

• Repositories:

• Just add, save and find

• Use of DQL implies the schema is too complex

• Controllers: 50 lines of code

• Application Services: Avoid business logic

• One step at time: Hex. Arch. -> DDD -> CQRS -> ES?

• Start it as a Module and promote it later to BC

TROLLTIMEQUESTIONS?

Akamon Developers