web campodessa zinchenko v2 (23-07-2014)
Embed Size (px)
DESCRIPTION
TRANSCRIPT

DDD in PHPon example of Symfony

cystbearSymfony expert
MongoDB adept
Erlang fun
OSS doer
KNPer
https://twitter.com/1cdecoderhttps://github.com/cystbearhttp://knplabs.com/

Learning Pyramid

PHP? ORLY?

What this talk about?

About useful tool/lib?

About success story?

No! It’s about idea
Motivation!

MVC

Where to store business logic?
ModelViewController

Where to store business logic?
ModelViewController

Where to store business logic?
ModelViewController

Where to store business logic?
ModelViewController -- YEAH!

Welcome to
Fat Stupid Ugly ControllersFSUC/FUC
http://blog.astrumfutura.com/2008/12/the-m-in-mvc-why-models-are-misunderstood-and-unappreciated/http://zendframework.ru/anonses/model-with-mvc
http://habrahabr.ru/post/175465/

Anemic (Domain) Model
http://www.martinfowler.com/bliki/AnemicDomainModel.htmlhttp://habrahabr.ru/post/224879/
“In essence the problem with anemic domain models is that they incur all of the costs of a domain model, without yielding any of the benefits.”
Martin Fowler

Persistence Layer
Model


What is
Not MVC (phew!)
Request / Response FrameworkHTTP Framework
http://fabien.potencier.org/article/49/what-is-symfony2

What about model,persistence layer?

Meet Doctrine
http://www.doctrine-project.org/
SQL -- DBAL + ORMMongoDBCouchDBOrientDBPHPCR ODMOXM

What is
Inversion of controlService LocatorDependency Injection Container
http://www.martinfowler.com/articles/injection.htmlhttp://fabien.potencier.org/article/11/what-is-dependency-injection

Services
http://groovy.codehaus.org/https://grails.org/
Single ClassWith its Deps (min) setEasy to ReplaceEasy to Test
MVC(S)!

Controller’s pray
https://twitter.com/ornicar
Get RequestSubmit form if anyCall one Service methodReturn Response
Rendering HTML far away

Managers Managers Managers
http://blog.codinghorror.com/i-shall-call-it-somethingmanager/http://stackoverflow.com/questions/1866794/naming-classes-how-to-
avoid-calling-everything-a-whatevermanager
<SmtManager><WhatEverManager><MyManager><EtcManager>

Real Painclass BackendUserProgramsPossessionFormHandler{ protected $dep1; // deps holder props
public function __construct(DepsClass $dep1 /*, ...*/) { $this->dep1 = $dep1; }
public function process(Form $form) { $this->dep1->makeHappy($form); // ... }

How Kris writes Symfony apps#44
https://twitter.com/kriswallsmithhttp://www.slideshare.net/kriswallsmith/how-kris-writessymfonyapps

https://twitter.com/kriswallsmithhttp://www.slideshare.net/kriswallsmith/how-kris-writessymfonyapps
How Kris writes Symfony apps#44

Domain Logic Patterns
http://martinfowler.com/books/eaa.html

Domain Logic Patterns
http://martinfowler.com/books/eaa.html
Transaction ScriptDomain ModelTable ModuleService Layer

Transaction Script

Domain Model

Table Module

Domain Logic&
Application logic

Service Layer


What is next?RADDDD PatternsExamplesLayersGoodies

DDD != RADCode FirstDo not Care about persistence (yet)

Domain ModelRepositoryValue ObjectDTOStrategyState
Patterns & Code

Domain Model

Domain Model<?php
namespace MegaCorp\Core\Product;
class Product{ private $id; private $name; private $recognitionStrategy;
public function __construct( ProductId $id, $name, $recognitionStrategy ) { $this->id = $id; $this->name = $name; $this->recognitionStrategy = $recognitionStrategy; }

Repository<?php
namespace MegaCorp\Core\Product;
interface ProductRepository{ public function find(ProductId $productId);
public function findAll();
public function add(Product $product);
public function remove(Product $product);}

Value Object<?php
namespace MegaCorp\Core;
class ProductId{ private $value;
public function __construct($value) { $this->value = (string) $value; }
public function getValue() { return $this->value; }}

Value Object DateRange

Value Object DateRange<?php
public function findByDateRange( \DateTime $from, \DateTime $to )
class DateRange{ private $from; private $to; public function __construct(\DateTime $from, \DateTime $to) { $this->from = $from; $this->to = $to; }}
public function findByDateRange(\DateRange $range)

Value Object Money

<?php
class Money{ private $amount; private $currency;
public function __construct($amount, Currency $currency) { // ... }}
Value Object Money

<?php
class ProfileData{ public $firstName; public $lastName; public $birthday;}
DTO

Strategy

______ ______ _______ _______ / | / __ \ | \ | ____|| ,----'| | | | | .--. || |__ | | | | | | | | | || __| | `----.| `--' | | '--' || |____ \______| \______/ |_______/ |_______|

src└── MegaCorp ├── ApiBundle │ ├── Controller │ │ └── ... │ └── MegaCorpApiBundle.php ├── Core │ └── Product │ ├── Product.php │ ├── ProductId.php │ └── ProductRepository.php └── CoreBundle ├── Controller │ └── ... ├── Repository │ ├── InMemoryProductRepository.php │ └── MongoDbProductRepository.php └── MegaCorpCoreBundle.php
Directory structure

Layers

LayersDomain Layer -- heart of your application, Entities and Repositories
Application Layer -- ControllersPresentation Layer -- Templates / DTOs for serializerInfrastructure Layer -- framework, persistence, concrete implementations of Domain Layer

Useful goodies

BBB DDD by Eric Evans
http://amzn.com/0321125215/

DDD Quickly by InfoQ
http://www.infoq.com/minibooks/domain-driven-design-quickly

PoEAA by Martin Fowler
http://amzn.com/B008OHVDFM/

DDD and Patterns by Jimmy Nilsson
http://amzn.com/B0054KOKQQ/

Linkshttp://dddcommunity.org/
http://williamdurand.fr/http://welcometothebundle.com/http://verraes.net/http://jimmynilsson.com/blog/http://www.martinfowler.com/
http://elephantintheroom.io/ -- podcast
http://msdn.microsoft.com/en-us/magazine/dd419654.aspxhttp://www.martinfowler.com/bliki/AnemicDomainModel.htmlhttp://martinfowler.com/bliki/CQRS.html
