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.
Domain-driven design (DDD) is an approach to software development for complex needs by connecting the implementation to an evolving model.[1] The premise of domain-driven design is the following:
Placing the project's primary focus on the core domain and domain logic.
Basing complex designs on a model of the domain.
Initiating a creative collaboration between technical and domain experts to iteratively refine a conceptual model that addresses particular domain problems.
Have more questions?
Twitter: @wajrcs
Web: http://waqaralamgir.tk
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
10. Laravel Framewrok
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.
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.
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
14. What is Command
Meat of the application
Controller
Artisan Command
Queue Worker
Whatever
15. What is Command
Meat of the application
Commands
i.e. Register Member
Command
16. What is Command
Meat of the application
Commands
i.e. Register Member
Command
17. Advantages
1. No business policy in your controller
2. Your code shows intent
3. A single dedicated flow per user case
4. A single point of entry per user case
5. Easy to see which use cased are implemented
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;
}
}
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;
}
}
20. The Final Destination
Register Member
Handler
Register Member
Command
Meat of the application
21. The Final Destination
Register Member
Handler
Register Member
Command
Meat of the application
Command Bus
34. A Common Application
PRESENTATION LAYER
Controllers
Artisan Commands
Queue Listeners
SERVICE LAYER
Sending Email
Queuing up Jobs
Repository Implementations
COMMANDS / COMMAND BUS
Event Dispatcher
DOMAIN
Entities
Repository Interface
Domain Events
35. Events/ Listener
Breakdown
Member Registers
Subscribe to Mail
Chimp
Send Welcome Email
Queue up 7 Day Email
36. class MemberRegistered
{
public $member;
public function __construct(Member $member)
{
$this->member = $member;
}
}
class SendWelcomeEmail implements Listener
{
public function handle($event)
{
Mailer ::Queue(…);
}
}
38. class EventGenerator
{
protected $pendingEvents = [];
public function raise($event)
{
$this->pendingEvents = $event;
}
public function releaseEvents()
{
$events = $this->pendingEvents;
$this->pendingEvents = [] ;
return $events;
}
}
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;
}
}
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) ;
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()) ;
}
}
42. More Information
About DDD
Domain-Driven Design: Tackling
Complexity in the Heart of
Software - Eric Evans
Implementing Domain-Driven
Design- Vaughn Vernon
43. Thank You!
Have more questions?
Email: walamgir@folio3.com
Twitter: @wajrcs