6. Entities
“Many objects are found
fundamentally by their
attributes but rather by a
thread of continuity and
identity” – Eric Evans
@folio_3 www.folio3.com Copyright 2015
9. Person
Waqar Alamgir
Age 26
From Karachi
Waqar Alamgir
Age 26
From Karachi
ID NAME AGE LOCATION
1 Waqar Alamgir 26 Karachi
2 Waqar Alamgir 26 Karachi
@folio_3 www.folio3.com Copyright 2015
10. Laravel is a free, open source PHP web application
framework, designed for the development of model–view–
controller (MVC) web applications. Laravel is listed as the
most popular PHP framework in 2013.
Eloquent ORM (object-relational mapping) is an advanced PHP
implementation of the active record pattern.
Better Routing.
Restful controllers provide an optional way for separating
the logic behind serving HTTP GET and POST requests.
Class auto loading.
Migrations provide a version control system for database
schemas.
Laravel Framewrok
@folio_3 Copyright 2015www.folio3.com
12. Philosophy
In building large scale web applications MVC
seems like a good solution in the initial
design phase. However after having built a
few large apps that have multiple entry
points (web, cli, api etc) you start to find
that MVC breaks down. Start using Domain
Driven Design.
@folio_3 www.folio3.com Copyright 2015
13. A Common Application
PRESENTATION LAYER
Controllers
Artisan Commands
Queue Listeners
SERVICE LAYER
Sending Email
Queuing up Jobs
Repository Implementations
COMMANDS / COMMAND BUS
DOMAIN
Entities
Repository Interface
@folio_3 www.folio3.com Copyright 2015
14. What is Command
Meat of the application
Controller
Artisan Command
Queue Worker
Whatever
@folio_3 www.folio3.com Copyright 2015
15. What is Command
Meat of the application
Commands
i.e. Register Member
Command
@folio_3 www.folio3.com Copyright 2015
16. What is Command
Meat of the application
Commands
i.e. Register Member
Command
@folio_3 www.folio3.com Copyright 2015
17. Advantages
1. No business policy in your controller
2. Your code shows intent
3. A single dedicated flow per use case
4. A single point of entry per use case
5. Easy to see which use cases are implemented
@folio_3 www.folio3.com Copyright 2015
18. Register Command
class RegisterMemberCommand
{
public $displayName;
public $email;
public $password;
public function __construct($displayName , $email ,
$password)
{
$this->displayName = $displayName;
$this->email = $email;
$this->password = $password;
}
}
@folio_3 www.folio3.com Copyright 2015
19. Register Command
class RegisterMemberCommand
{
public $displayName;
public $email;
public $password;
public function __construct($displayName , $email ,
$password)
{
$this->displayName = $displayName;
$this->email = $email;
$this->password = $password;
}
}
@folio_3 www.folio3.com Copyright 2015
20. The Final Destination
Register Member
Handler
Register Member
Command
Meat of the application
@folio_3 www.folio3.com Copyright 2015
21. The Final Destination
Register Member
Handler
Register Member
Command
Meat of the application
Command Bus
@folio_3 www.folio3.com Copyright 2015
36. class MemberRegistered
{
public $member;
public function __construct(Member $member)
{
$this->member = $member;
}
}
class SendWelcomeEmail implements Listener
{
public function handle($event)
{
Mailer ::Queue(…);
}
}
@folio_3 www.folio3.com Copyright 2015
38. class EventGenerator
{
protected $pendingEvents = [];
public function raise($event)
{
$this->pendingEvents = $event;
}
public function releaseEvents()
{
$events = $this->pendingEvents;
$this->pendingEvents = [] ;
return $events;
}
}
@folio_3 www.folio3.com Copyright 2015
39. class Member extends Eloquent
{
use EventGenerator ;
public static function register($displayName , $email ,
$password)
{
$member = new static([
‘display_name’ => $displayName,
‘email’ => $email,
‘password’ => $password
]);
$member->raise(new MemberRegistered($member)) ;
return $member;
}
}
@folio_3 www.folio3.com Copyright 2015
40. Interface Dispatcher
{
public function addListener($eventName , Listener
$listener) ;
public function dispatch($events) ;
}
// Register Listeners
$dispatcher = new Dispatcher() ;
$dispatcher-> addListener(‘MemberRegistered’ , new
SubscribeToMailchimp) ;
$dispatcher-> addListener(‘MemberRegistered’ , new
SendWelcomeEmail) ;
$dispatcher-> addListener(‘MemberRegistered’ , new
SendOneWeekEmail) ;
@folio_3 www.folio3.com Copyright 2015
41. class RegisterMemberHandler implements Handler
{
private $memberRepository;
private $dispatcher;
public function __construct(MemberRepository
$memberRepository , Dispatcher $dispatcher)
{
$this->memberRepository = $memberRepository;
$this-> dispatcher = $dispatcher ;
}
public function handle($command)
{
$member = Member::register(
$command->displayName, $command->email,
$command->password
);
$this->memberRepository->save($member);
$this->dispatcher->dispatch($member->
releaseEvents()) ;
}
}
@folio_3 www.folio3.com Copyright 2015
42. More Information
About DDD
Domain-Driven Design: Tackling
Complexity in the Heart of
Software - Eric Evans
Implementing Domain-Driven
Design- Vaughn Vernon
@folio_3 www.folio3.com Copyright 2015