SlideShare une entreprise Scribd logo
1  sur  60
Télécharger pour lire hors ligne
Confoo 2015
Beyond MVC: From
Model to Domain
Jeremy Cook
What is a domain?
–http://www.oxforddictionaries.com/definition/english/domain
“a specified sphere of activity or knowledge.”
–http://en.wikipedia.org/wiki/Domain_(software_engineering)
“A domain is a field of study that defines a set of
common requirements, terminology, and
functionality for any software program
constructed to solve a problem…”
What is MVC?
Interaction of MVC Layers
User
Model
Controller
Uses
Manipulates
View
Updates
Sees
Interaction of MVC Layers
User
Model
Controller
View
Problems with ‘web’ MVC
❖ Use of the term ‘Model’ is an issue…
❖ Easy to muddy responsibilities in the controller
❖ Offers no guidance in modelling the most critical part of
our apps: the model or domain
–http://en.wikipedia.org/wiki/Model–view–controller
“Model–view–controller (MVC) is a software
architectural pattern for implementing user
interfaces.”
This talk is about managing
complexity
Introducing Action Domain
Responder
What is Action Domain Responder?
❖ Created by Paul M Jones
❖ Web specific refinement of MVC
❖ Designed to map more closely to what actually happens
in the lifecycle of a web request
What is Action Domain Responder?
❖ Model
❖ View
❖ Controller
What is Action Domain Responder?
❖ Controller
❖ Model
❖ View
What is Action Domain Responder?
❖ Controller Action
❖ Model Domain
❖ View Responder
Action
❖ In ADR an action is mapped to a single class or closure
❖ Creates a single place for all code dealing with an action
❖ Does not directly create a view or HTTP response
Responder
❖ ADR recognizes that a web response is more than a
view
❖ Action instantiates a responder object and injects
domain data in it
❖ Responder is responsible for generating all aspects of
the response
Domain
❖ ADR offers no help on modelling a domain…
❖ …but at least Paul calls it a domain!
❖ Other patterns later will offer more help here
ADR Example
<?php
interface ActionInterface {
public function __construct(ResponderFactoryInterface $factory);
public function __invoke(RequestInterface $request);
}
ADR Example
<?php
class FooAction implements ActionInterface {
protected $responderFactory;
public function __construct(ResponderFactoryInterface $factory) {
$this->responderFactory = $factory;
}
public function __invoke(RequestInterface $request) {
//Domain logic here
$responder = $this->responderFactory->generateForRequest($request);
return $responder();
}
}
Further information on ADR
❖ https://github.com/pmjones/adr
Hexagonal Architecture
Ports and Adapters
Hexagonal Architecture
What’s wrong with ‘Hexagonal Architecture’?
❖ Has nothing to do with hexagons
❖ Has nothing to do with the number 6
❖ Ports and adapters describes what this actually does
What are Ports and Adapters?
❖ Invented by Alistair Cockburn
❖ Architectural pattern for isolating an application from
its inputs.
–Alistair Cockburn
“Allow an application to equally be driven by
users, programs, automated test or batch scripts,
and to be developed and tested in isolation from
its eventual run-time devices and databases.”
–Alistair Cockburn
“Allow an application to equally be driven by
users, programs, automated test or batch scripts,
and to be developed and tested in isolation from
its eventual run-time devices and databases.”
Ports and Adapters
Application
Ports and Adapters
Application
Ports and Adapters
Application
Adapters Adapters
Adapters
Adapters
AdaptersAdapters
Ports and Adapters
Domain
Adapters Adapters
Adapters
Adapters
AdaptersAdapters
HTTP Adapter
<?php
class FooAction implements ActionInterface {
protected $responderFactory;
protected $service;
public function __construct(ResponderFactoryInterface $factory,
ApplicationServiceInterface $service) {
$this->responderFactory = $factory;
$this->service = $service;
}
public function __invoke(RequestInterface $request) {
$result = $this->service->__invoke($request->getParamsArray());
$responder = $this->responderFactory->generateForRequest($request);
return $responder($result);
}
}
AMQP Adapter
<?php
class FooConsumer implements AMQPConsumer {
protected $service;
public function __construct(ApplicationServiceInterface $service) {
$this->service = $service;
}
public function __invoke(AMQPMessage $msg) {
$data = json_decode($msg->body, true);
$result = $this->service->__invoke($data);
if ($result->isStatusOk()) {
$msg->delivery_info['channel']
->basic_ack($msg->delivery_info['delivery_tag']);
}
}
}
Advantages of Ports and Adapters
❖ Encapsulation of the domain
❖ Allows development of the domain and adapters to
be independent
❖ Allows better end to end testability of the domain
❖ Makes it simple to add new entry points to an app
Further information on Ports and Adapters
❖ The original article introducing ports and adapters:
http://alistair.cockburn.us/Hexagonal+architecture
Introducing Domain Driven
Design
What is Domain Driven Design?
❖ Concept coined by Eric Evans
❖ Ideas can be grouped into two related areas:
❖ Architectural patterns
❖ Object patterns
DDD Interaction Map
Read some books
Architectural patterns
Your app has multiple domains
Ubiquitous language
❖ Develop a shared language to describe each domain
and model the software after it
❖ The domain should be an expression of the ubiquitous
language in code
❖ Aim is to unite all members of a product team, from
developers to product managers
Bounded contexts
❖ Represents the boundary around a domain
❖ All code within a domain is completely encapsulated
with specific entry points
❖ Code and concepts are unique per domain
Context map
❖ Describes relationships between domains
❖ Outlines all points of contact between domains
❖ Can also include existing systems
Object patterns
Entities
❖ Represents a concept in your domain
❖ Each instance of a entity should be considered unique
❖ Houses logic and operation on the concept
Value Objects
❖ Used when you only care about the attributes and logic
of the concept
❖ Immutable
❖ All methods must be side effect free
❖ Mutator methods must return a new instance of the
value object
❖ Prefer value objects over simple types
Value Objects
<?php
class Employee {
public function __construct($firstName, $lastName) {
//Code here
}
}
$person = new Employee('Cook', 'Jeremy'); //WHOOPS!
Value Objects
<?php
class Firstname {
protected $firstname;
public function __construct($firstname) {
if (! is_string($firstname)) {
throw new InvalidArgumentException(/**ErrorMessage**/);
}
$this->firstname = $firstname;
}
public function __toString() {
return $this->firstname;
}
}
Value Objects
<?php
class Employee {
public function __construct(Firstname $firstName, Lastname $lastName) {
//Code here
}
}
//This will now cause an error
$person = new Employee(new Lastname('Cook'), new Firstname('Jeremy'));
Entities vs Value Objects
!==
Bank Account
Owner: Jeremy
Balance: $1,000,000
Account #: 12345
===
Currency
Name: Canadian Dollar
Abbr: CAD
Symbol: $
Currency
Name: Canadian Dollar
Abbr: CAD
Symbol: $
Bank Account
Owner: Jeremy
Balance: $1,000,000
Account #: 12346
Domain Services
❖ Encapsulates an operation that is not owned by another
part of the domain model
❖ A good service has three properties:
❖ Models a domain concept that does not conceptually
belong to an entity or value object
❖ Stateless
❖ Defined in terms of the domain model
Domain Services
<?php
class MoneyTransfer {
public static function transferBetweenAccounts(Account $from, Account
$to, Money $amount) {
$from->debitForTransfer($money, $to);
$to->creditFromTransfer($money, $from);
}
}
//In the application service...
$from = $accountRepository->findByAccNumber('123456');
$to = $accountRepository->findByAccNumber('123457');
$money = new Money('100', new Currency('CAD'));
MoneyTransfer::transferBetweenAccounts($from, $to, $money);
Aggregates
❖ A collection of entities contained by another entity
❖ The containing entity is the aggregate root
❖ Individual aggregate instances can only be accessed
through the aggregate root
Repositories
❖ A specialised adapter that maps entities to and from the
persistence layer
❖ Provides methods to retrieve entities and save them
❖ Abstracts the details of the persistence layer away from
the domain
Domain Events
❖ Allows a domain to signal that something as happened
❖ Full part of the domain and a representation of
something that has happened
❖ Used to signal something that might trigger a state
change in another domain
Domain Events
$event = EventFactory::createEventForSuccessfulAccountTransfer($from, $to,
$money);
$eventType = EventTypes::SUCCESSFUL_MONEY_TRANSFER;
$eventDispatcher->raiseEvent($eventType, $event);
<?php
class MoneyTransfer {
public static function transferBetweenAccounts(Account $from, Account
$to, Money $amount) {
$from->debitForTransfer($money, $to);
$to->creditFromTransfer($money, $from);
}
}
//In the application service...
$from = $accountRepository->findByAccNumber('123456');
$to = $accountRepository->findByAccNumber('123457');
$money = new Money('100', new Currency('CAD'));
MoneyTransfer::transferBetweenAccounts($from, $to, $money);
Further Information on DDD
❖ Eric Evans
❖ “Domain Driven Design” book
❖ Short introduction: https://domainlanguage.com/
ddd/patterns/DDD_Reference_2011-01-31.pdf
❖ Implementing Domain Driven Design by Vaughn
Vernon
Avoid projects like this!
Thanks for listening!
❖ Any questions?
❖ I’d love some feedback
❖ Feel free to contact me
❖ jeremycook0@icloud.com
❖ @JCook21

Contenu connexe

Similaire à Beyond MVC: from Model to Domain

Beyond MVC: from Model to Domain
Beyond MVC: from Model to DomainBeyond MVC: from Model to Domain
Beyond MVC: from Model to DomainJeremy Cook
 
Dicoding Developer Coaching #31: Android | Menerapkan Clean Architecture di A...
Dicoding Developer Coaching #31: Android | Menerapkan Clean Architecture di A...Dicoding Developer Coaching #31: Android | Menerapkan Clean Architecture di A...
Dicoding Developer Coaching #31: Android | Menerapkan Clean Architecture di A...DicodingEvent
 
Crafted Design - Sandro Mancuso
Crafted Design - Sandro MancusoCrafted Design - Sandro Mancuso
Crafted Design - Sandro MancusoJAXLondon2014
 
Dependency injection Drupal Camp Wrocław 2014
Dependency injection Drupal Camp Wrocław 2014Dependency injection Drupal Camp Wrocław 2014
Dependency injection Drupal Camp Wrocław 2014Greg Szczotka
 
Angular mobile angular_u
Angular mobile angular_uAngular mobile angular_u
Angular mobile angular_uDoris Chen
 
Crafted Design - LJC World Tour Mash Up 2014
Crafted Design - LJC World Tour Mash Up 2014Crafted Design - LJC World Tour Mash Up 2014
Crafted Design - LJC World Tour Mash Up 2014Sandro Mancuso
 
Code decoupling from Symfony (and others frameworks) - PHP Conference Brasil ...
Code decoupling from Symfony (and others frameworks) - PHP Conference Brasil ...Code decoupling from Symfony (and others frameworks) - PHP Conference Brasil ...
Code decoupling from Symfony (and others frameworks) - PHP Conference Brasil ...Miguel Gallardo
 
Crafted Design - ITAKE 2014
Crafted Design - ITAKE 2014Crafted Design - ITAKE 2014
Crafted Design - ITAKE 2014Sandro Mancuso
 
Crafted Design - GeeCON 2014
Crafted Design - GeeCON 2014Crafted Design - GeeCON 2014
Crafted Design - GeeCON 2014Sandro Mancuso
 
From Backbone to Ember and Back(bone) Again
From Backbone to Ember and Back(bone) AgainFrom Backbone to Ember and Back(bone) Again
From Backbone to Ember and Back(bone) Againjonknapp
 
Osiąganie mądrej architektury z Symfony2
Osiąganie mądrej architektury z Symfony2 Osiąganie mądrej architektury z Symfony2
Osiąganie mądrej architektury z Symfony2 3camp
 
An Introduction to Domain Driven Design in PHP
An Introduction to Domain Driven Design in PHPAn Introduction to Domain Driven Design in PHP
An Introduction to Domain Driven Design in PHPChris Renner
 
Domain-driven Design in PHP and Symfony - Drupal Camp Wroclaw!
Domain-driven Design in PHP and Symfony - Drupal Camp Wroclaw!Domain-driven Design in PHP and Symfony - Drupal Camp Wroclaw!
Domain-driven Design in PHP and Symfony - Drupal Camp Wroclaw!Kacper Gunia
 
Framework engineering JCO 2011
Framework engineering JCO 2011Framework engineering JCO 2011
Framework engineering JCO 2011YoungSu Son
 
Hexagonal architecture - message-oriented software design
Hexagonal architecture  - message-oriented software designHexagonal architecture  - message-oriented software design
Hexagonal architecture - message-oriented software designMatthias Noback
 

Similaire à Beyond MVC: from Model to Domain (20)

Beyond MVC: from Model to Domain
Beyond MVC: from Model to DomainBeyond MVC: from Model to Domain
Beyond MVC: from Model to Domain
 
Hexagonal architecture
Hexagonal architectureHexagonal architecture
Hexagonal architecture
 
Dicoding Developer Coaching #31: Android | Menerapkan Clean Architecture di A...
Dicoding Developer Coaching #31: Android | Menerapkan Clean Architecture di A...Dicoding Developer Coaching #31: Android | Menerapkan Clean Architecture di A...
Dicoding Developer Coaching #31: Android | Menerapkan Clean Architecture di A...
 
Hexagonal architecture in PHP
Hexagonal architecture in PHPHexagonal architecture in PHP
Hexagonal architecture in PHP
 
Crafted Design - Sandro Mancuso
Crafted Design - Sandro MancusoCrafted Design - Sandro Mancuso
Crafted Design - Sandro Mancuso
 
Dependency injection Drupal Camp Wrocław 2014
Dependency injection Drupal Camp Wrocław 2014Dependency injection Drupal Camp Wrocław 2014
Dependency injection Drupal Camp Wrocław 2014
 
Angular mobile angular_u
Angular mobile angular_uAngular mobile angular_u
Angular mobile angular_u
 
Crafted Design - LJC World Tour Mash Up 2014
Crafted Design - LJC World Tour Mash Up 2014Crafted Design - LJC World Tour Mash Up 2014
Crafted Design - LJC World Tour Mash Up 2014
 
Code decoupling from Symfony (and others frameworks) - PHP Conference Brasil ...
Code decoupling from Symfony (and others frameworks) - PHP Conference Brasil ...Code decoupling from Symfony (and others frameworks) - PHP Conference Brasil ...
Code decoupling from Symfony (and others frameworks) - PHP Conference Brasil ...
 
Crafted Design - ITAKE 2014
Crafted Design - ITAKE 2014Crafted Design - ITAKE 2014
Crafted Design - ITAKE 2014
 
Crafted Design - GeeCON 2014
Crafted Design - GeeCON 2014Crafted Design - GeeCON 2014
Crafted Design - GeeCON 2014
 
Clean Architecture @ Taxibeat
Clean Architecture @ TaxibeatClean Architecture @ Taxibeat
Clean Architecture @ Taxibeat
 
From Backbone to Ember and Back(bone) Again
From Backbone to Ember and Back(bone) AgainFrom Backbone to Ember and Back(bone) Again
From Backbone to Ember and Back(bone) Again
 
Osiąganie mądrej architektury z Symfony2
Osiąganie mądrej architektury z Symfony2 Osiąganie mądrej architektury z Symfony2
Osiąganie mądrej architektury z Symfony2
 
An Introduction to Domain Driven Design in PHP
An Introduction to Domain Driven Design in PHPAn Introduction to Domain Driven Design in PHP
An Introduction to Domain Driven Design in PHP
 
Domain-driven Design in PHP and Symfony - Drupal Camp Wroclaw!
Domain-driven Design in PHP and Symfony - Drupal Camp Wroclaw!Domain-driven Design in PHP and Symfony - Drupal Camp Wroclaw!
Domain-driven Design in PHP and Symfony - Drupal Camp Wroclaw!
 
L03 Software Design
L03 Software DesignL03 Software Design
L03 Software Design
 
Framework engineering JCO 2011
Framework engineering JCO 2011Framework engineering JCO 2011
Framework engineering JCO 2011
 
Ruby On Rails Introduction
Ruby On Rails IntroductionRuby On Rails Introduction
Ruby On Rails Introduction
 
Hexagonal architecture - message-oriented software design
Hexagonal architecture  - message-oriented software designHexagonal architecture  - message-oriented software design
Hexagonal architecture - message-oriented software design
 

Plus de Jeremy Cook

Unit test your java architecture with ArchUnit
Unit test your java architecture with ArchUnitUnit test your java architecture with ArchUnit
Unit test your java architecture with ArchUnitJeremy Cook
 
Tracking your data across the fourth dimension
Tracking your data across the fourth dimensionTracking your data across the fourth dimension
Tracking your data across the fourth dimensionJeremy Cook
 
Tracking your data across the fourth dimension
Tracking your data across the fourth dimensionTracking your data across the fourth dimension
Tracking your data across the fourth dimensionJeremy Cook
 
Track your data across the fourth dimension
Track your data across the fourth dimensionTrack your data across the fourth dimension
Track your data across the fourth dimensionJeremy Cook
 
Accelerate your web app with a layer of Varnish
Accelerate your web app with a layer of VarnishAccelerate your web app with a layer of Varnish
Accelerate your web app with a layer of VarnishJeremy Cook
 
Turbo charge your logs
Turbo charge your logsTurbo charge your logs
Turbo charge your logsJeremy Cook
 
Turbo charge your logs
Turbo charge your logsTurbo charge your logs
Turbo charge your logsJeremy Cook
 
PHPUnit: from zero to hero
PHPUnit: from zero to heroPHPUnit: from zero to hero
PHPUnit: from zero to heroJeremy Cook
 

Plus de Jeremy Cook (8)

Unit test your java architecture with ArchUnit
Unit test your java architecture with ArchUnitUnit test your java architecture with ArchUnit
Unit test your java architecture with ArchUnit
 
Tracking your data across the fourth dimension
Tracking your data across the fourth dimensionTracking your data across the fourth dimension
Tracking your data across the fourth dimension
 
Tracking your data across the fourth dimension
Tracking your data across the fourth dimensionTracking your data across the fourth dimension
Tracking your data across the fourth dimension
 
Track your data across the fourth dimension
Track your data across the fourth dimensionTrack your data across the fourth dimension
Track your data across the fourth dimension
 
Accelerate your web app with a layer of Varnish
Accelerate your web app with a layer of VarnishAccelerate your web app with a layer of Varnish
Accelerate your web app with a layer of Varnish
 
Turbo charge your logs
Turbo charge your logsTurbo charge your logs
Turbo charge your logs
 
Turbo charge your logs
Turbo charge your logsTurbo charge your logs
Turbo charge your logs
 
PHPUnit: from zero to hero
PHPUnit: from zero to heroPHPUnit: from zero to hero
PHPUnit: from zero to hero
 

Dernier

Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherRemote DBA Services
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...DianaGray10
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024The Digital Insurer
 
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...Principled Technologies
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobeapidays
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024SynarionITSolutions
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024The Digital Insurer
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProduct Anonymous
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesBoston Institute of Analytics
 

Dernier (20)

Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
Connector Corner: Accelerate revenue generation using UiPath API-centric busi...
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024Manulife - Insurer Innovation Award 2024
Manulife - Insurer Innovation Award 2024
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation Strategies
 

Beyond MVC: from Model to Domain

  • 1. Confoo 2015 Beyond MVC: From Model to Domain Jeremy Cook
  • 2. What is a domain?
  • 4. –http://en.wikipedia.org/wiki/Domain_(software_engineering) “A domain is a field of study that defines a set of common requirements, terminology, and functionality for any software program constructed to solve a problem…”
  • 6. Interaction of MVC Layers User Model Controller Uses Manipulates View Updates Sees
  • 7. Interaction of MVC Layers User Model Controller View
  • 8. Problems with ‘web’ MVC ❖ Use of the term ‘Model’ is an issue… ❖ Easy to muddy responsibilities in the controller ❖ Offers no guidance in modelling the most critical part of our apps: the model or domain
  • 9. –http://en.wikipedia.org/wiki/Model–view–controller “Model–view–controller (MVC) is a software architectural pattern for implementing user interfaces.”
  • 10. This talk is about managing complexity
  • 12. What is Action Domain Responder? ❖ Created by Paul M Jones ❖ Web specific refinement of MVC ❖ Designed to map more closely to what actually happens in the lifecycle of a web request
  • 13. What is Action Domain Responder? ❖ Model ❖ View ❖ Controller
  • 14. What is Action Domain Responder? ❖ Controller ❖ Model ❖ View
  • 15. What is Action Domain Responder? ❖ Controller Action ❖ Model Domain ❖ View Responder
  • 16. Action ❖ In ADR an action is mapped to a single class or closure ❖ Creates a single place for all code dealing with an action ❖ Does not directly create a view or HTTP response
  • 17. Responder ❖ ADR recognizes that a web response is more than a view ❖ Action instantiates a responder object and injects domain data in it ❖ Responder is responsible for generating all aspects of the response
  • 18. Domain ❖ ADR offers no help on modelling a domain… ❖ …but at least Paul calls it a domain! ❖ Other patterns later will offer more help here
  • 19. ADR Example <?php interface ActionInterface { public function __construct(ResponderFactoryInterface $factory); public function __invoke(RequestInterface $request); }
  • 20. ADR Example <?php class FooAction implements ActionInterface { protected $responderFactory; public function __construct(ResponderFactoryInterface $factory) { $this->responderFactory = $factory; } public function __invoke(RequestInterface $request) { //Domain logic here $responder = $this->responderFactory->generateForRequest($request); return $responder(); } }
  • 21. Further information on ADR ❖ https://github.com/pmjones/adr
  • 24. What’s wrong with ‘Hexagonal Architecture’? ❖ Has nothing to do with hexagons ❖ Has nothing to do with the number 6 ❖ Ports and adapters describes what this actually does
  • 25. What are Ports and Adapters? ❖ Invented by Alistair Cockburn ❖ Architectural pattern for isolating an application from its inputs.
  • 26. –Alistair Cockburn “Allow an application to equally be driven by users, programs, automated test or batch scripts, and to be developed and tested in isolation from its eventual run-time devices and databases.”
  • 27. –Alistair Cockburn “Allow an application to equally be driven by users, programs, automated test or batch scripts, and to be developed and tested in isolation from its eventual run-time devices and databases.”
  • 30. Ports and Adapters Application Adapters Adapters Adapters Adapters AdaptersAdapters
  • 31. Ports and Adapters Domain Adapters Adapters Adapters Adapters AdaptersAdapters
  • 32. HTTP Adapter <?php class FooAction implements ActionInterface { protected $responderFactory; protected $service; public function __construct(ResponderFactoryInterface $factory, ApplicationServiceInterface $service) { $this->responderFactory = $factory; $this->service = $service; } public function __invoke(RequestInterface $request) { $result = $this->service->__invoke($request->getParamsArray()); $responder = $this->responderFactory->generateForRequest($request); return $responder($result); } }
  • 33. AMQP Adapter <?php class FooConsumer implements AMQPConsumer { protected $service; public function __construct(ApplicationServiceInterface $service) { $this->service = $service; } public function __invoke(AMQPMessage $msg) { $data = json_decode($msg->body, true); $result = $this->service->__invoke($data); if ($result->isStatusOk()) { $msg->delivery_info['channel'] ->basic_ack($msg->delivery_info['delivery_tag']); } } }
  • 34. Advantages of Ports and Adapters ❖ Encapsulation of the domain ❖ Allows development of the domain and adapters to be independent ❖ Allows better end to end testability of the domain ❖ Makes it simple to add new entry points to an app
  • 35. Further information on Ports and Adapters ❖ The original article introducing ports and adapters: http://alistair.cockburn.us/Hexagonal+architecture
  • 37. What is Domain Driven Design? ❖ Concept coined by Eric Evans ❖ Ideas can be grouped into two related areas: ❖ Architectural patterns ❖ Object patterns
  • 41. Your app has multiple domains
  • 42. Ubiquitous language ❖ Develop a shared language to describe each domain and model the software after it ❖ The domain should be an expression of the ubiquitous language in code ❖ Aim is to unite all members of a product team, from developers to product managers
  • 43. Bounded contexts ❖ Represents the boundary around a domain ❖ All code within a domain is completely encapsulated with specific entry points ❖ Code and concepts are unique per domain
  • 44. Context map ❖ Describes relationships between domains ❖ Outlines all points of contact between domains ❖ Can also include existing systems
  • 46. Entities ❖ Represents a concept in your domain ❖ Each instance of a entity should be considered unique ❖ Houses logic and operation on the concept
  • 47. Value Objects ❖ Used when you only care about the attributes and logic of the concept ❖ Immutable ❖ All methods must be side effect free ❖ Mutator methods must return a new instance of the value object ❖ Prefer value objects over simple types
  • 48. Value Objects <?php class Employee { public function __construct($firstName, $lastName) { //Code here } } $person = new Employee('Cook', 'Jeremy'); //WHOOPS!
  • 49. Value Objects <?php class Firstname { protected $firstname; public function __construct($firstname) { if (! is_string($firstname)) { throw new InvalidArgumentException(/**ErrorMessage**/); } $this->firstname = $firstname; } public function __toString() { return $this->firstname; } }
  • 50. Value Objects <?php class Employee { public function __construct(Firstname $firstName, Lastname $lastName) { //Code here } } //This will now cause an error $person = new Employee(new Lastname('Cook'), new Firstname('Jeremy'));
  • 51. Entities vs Value Objects !== Bank Account Owner: Jeremy Balance: $1,000,000 Account #: 12345 === Currency Name: Canadian Dollar Abbr: CAD Symbol: $ Currency Name: Canadian Dollar Abbr: CAD Symbol: $ Bank Account Owner: Jeremy Balance: $1,000,000 Account #: 12346
  • 52. Domain Services ❖ Encapsulates an operation that is not owned by another part of the domain model ❖ A good service has three properties: ❖ Models a domain concept that does not conceptually belong to an entity or value object ❖ Stateless ❖ Defined in terms of the domain model
  • 53. Domain Services <?php class MoneyTransfer { public static function transferBetweenAccounts(Account $from, Account $to, Money $amount) { $from->debitForTransfer($money, $to); $to->creditFromTransfer($money, $from); } } //In the application service... $from = $accountRepository->findByAccNumber('123456'); $to = $accountRepository->findByAccNumber('123457'); $money = new Money('100', new Currency('CAD')); MoneyTransfer::transferBetweenAccounts($from, $to, $money);
  • 54. Aggregates ❖ A collection of entities contained by another entity ❖ The containing entity is the aggregate root ❖ Individual aggregate instances can only be accessed through the aggregate root
  • 55. Repositories ❖ A specialised adapter that maps entities to and from the persistence layer ❖ Provides methods to retrieve entities and save them ❖ Abstracts the details of the persistence layer away from the domain
  • 56. Domain Events ❖ Allows a domain to signal that something as happened ❖ Full part of the domain and a representation of something that has happened ❖ Used to signal something that might trigger a state change in another domain
  • 57. Domain Events $event = EventFactory::createEventForSuccessfulAccountTransfer($from, $to, $money); $eventType = EventTypes::SUCCESSFUL_MONEY_TRANSFER; $eventDispatcher->raiseEvent($eventType, $event); <?php class MoneyTransfer { public static function transferBetweenAccounts(Account $from, Account $to, Money $amount) { $from->debitForTransfer($money, $to); $to->creditFromTransfer($money, $from); } } //In the application service... $from = $accountRepository->findByAccNumber('123456'); $to = $accountRepository->findByAccNumber('123457'); $money = new Money('100', new Currency('CAD')); MoneyTransfer::transferBetweenAccounts($from, $to, $money);
  • 58. Further Information on DDD ❖ Eric Evans ❖ “Domain Driven Design” book ❖ Short introduction: https://domainlanguage.com/ ddd/patterns/DDD_Reference_2011-01-31.pdf ❖ Implementing Domain Driven Design by Vaughn Vernon
  • 60. Thanks for listening! ❖ Any questions? ❖ I’d love some feedback ❖ Feel free to contact me ❖ jeremycook0@icloud.com ❖ @JCook21

Notes de l'éditeur

  1. This as an introductory talk. I’m going to introduce a number of architectural and structural patterns that can help you model your business domains better. There is no single bullet solution… Begin with some level setting
  2. Dictionary definition
  3. Domain include all code needed to model a particular business problem. Domain layer in an app can imply encapsulation. I’m going to argue that encapsulating a domain is something we should strive for…
  4. I want to talk about what MVC historically was, why it was adapted for the web and what the compromises are when using it. MVC for the web is a corrupted pattern…
  5. MVC first developed in the 70’s and 80’s by Trygve Reenskaug, Jim Althoff and others
  6. MVC as it’s generally used on the web.
  7. MVC is about separation of concerns. Without care domain and view logic leaks into controllers, which breaks SOC. We tend to think of a model (singular). Controller often becomes the place where data is marshalled between models. View is also controlled by the controller.
  8. Modern web apps are about far more than just user interfaces. Throws the focus on the UI when mostly now it’s about the data that’s stored. Apps are as much about the data and how it is represented than the UI itself.
  9. All of the solutions today can increase the complexity of your codebase. This should set your alarm bells ringing!! It’s about exchanging unmanageable complexity for managed complexity. As requirements grow and change code can easily become unmanageable. This is when you need to move beyond MVC.
  10. Straight up: ADR is not a solution to the problem I’m looking at but a different way of looking at the problem. ADR helps us to get back to more easily separating concerns.
  11. Each of the three concepts implies a subtle shift in thinking.
  12. We’re used to controllers with many actions. Additional wrapper logic could be pre or post action hooks. Allows the action to assume all responsibility for a single action.
  13. Web response is more than a view! Many MVC frameworks have controller manipulating elements of the response. Responder is responsible for deciding the HTTP status code, setting headers, etc as well as generating the response body
  14. Could wrap this in a decorator if want before/after hooks
  15. Hopefully ADR has whetted your appetite.
  16. If I say hexagonal architecture what do you think of?
  17. Nevertheless, I will use hexagons and maybe the term hexagonal architecture in this talk!
  18. This quote describes the intent of the pattern.
  19. Database is an implementation detail. Don’t build your objects to simply ‘sit on top of’ database tables but allow them to be mapped onto a persistence medium. Think firstly in terms of object relationships. This is a core tenant of DDD will be elaborated on later…
  20. Move to next slide!
  21. Adapters sit inside the application boundary but not inside the domain boundary Adapter shuffles data between the input type and the domain, also dealing with a response. Adapters and domain are only lightly coupled. The domain has no idea about the types of input and output. Adapters have no idea how the domain is implemented.
  22. If a domain is properly encapsulated then a controller/action is an adapter…
  23. DDD places the design of the domain at the heart of the application development. Nothing new but codifies best practices.
  24. I can only scratch the surface of this today… I’ll try to introduce some of the most important concepts.
  25. Blue book: theoretical. Red book: practical
  26. Really architectural best practices
  27. Talk about core and supporting domains. Introduce idea of a domain model, the concept of the code model of the domain.
  28. Using different language between dev’s and domain experts leads to misunderstanding and communication failures. Intention revealing interface A change in the ubiquitous language is a change to the model. Ubiquitous language is unique to a bounded context/domain.
  29. Bounded contexts allow the app to be split up. Code is (almost) never shared between domains
  30. No domain exists in isolation Upstream and downstream domains, mutually dependent domains.
  31. 2 instances of the same entity with the same attributes are not the same! Avoid anemic domain entities. Can include data from more than one table!
  32. Also represents a concept in your domain… Value objects should be as common as entities, if not more so, in your domain. Mutator/side effect free method example: DateTimeImmutable::modify() Equality of value objects must be calculated based on their attributes, not identity Side effect free function produces output without modifying its own state.
  33. Entities can have value objects as properties
  34. It’s all about identity.
  35. Different from application service… Name of the service should be part of the ubiquitous language
  36. Example of moving money between two bank accounts (entities). Transfer is not owned by either account.
  37. Give an example of aggregate roots and aggregates, e.g. leagues -> seasons -> games -> game events
  38. Rationale: database access code can overwhelm domain model. Leads to dumbed down model, the opposite of what we want. Just querying for individual fields does not express anything about the domain model, again watering this down. Repository presents a very simple interface for an incredibly complex operation! Look at patterns such as: data mapper, unit of work, query object
  39. Mention overhead in dealing with multiple domains Mention synchronous and asynchronous events
  40. Need to consider the question of what information needs to be consistent immediately across domains and what can wait.