Domain Driven Design
-
Upload
pascal-larocque -
Category
Technology
-
view
948 -
download
3
description
Transcript of Domain Driven Design
![Page 1: Domain Driven Design](https://reader034.fdocuments.net/reader034/viewer/2022051816/546d47b7af795963268b4858/html5/thumbnails/1.jpg)
DOMAIN DRIVEN DESIGN
TACKLING COMPLEXITY
![Page 2: Domain Driven Design](https://reader034.fdocuments.net/reader034/viewer/2022051816/546d47b7af795963268b4858/html5/thumbnails/2.jpg)
@pascallarocque
○ TRUSTCHARGE TEAM
○ BEHAT GUY
○ TDD GUY
○ SOLID GUY
○ PATTERN GUY
○ FATHER OF 3
○ STAR WARS GEEK
![Page 3: Domain Driven Design](https://reader034.fdocuments.net/reader034/viewer/2022051816/546d47b7af795963268b4858/html5/thumbnails/3.jpg)
SOFTWARE IS COMPLICATED
![Page 4: Domain Driven Design](https://reader034.fdocuments.net/reader034/viewer/2022051816/546d47b7af795963268b4858/html5/thumbnails/4.jpg)
CURRENT ARCHITECTURE
CONTROLLER
ORM
DATABASE
APPLICATION
DATA ACCESS /
BUSINESS OBJECT/
PERSISTENCE
DATA STORE
BZ
● BUSINESS LOGIC IN
CONTROLLER AND IN DATA
ACCESS OBJECTS
● FRAMEWORK COUPLED TO
CONTROLLER
● DIRECT ACCESS TO DATA
OBJECT FROM CONTROLLER
![Page 5: Domain Driven Design](https://reader034.fdocuments.net/reader034/viewer/2022051816/546d47b7af795963268b4858/html5/thumbnails/5.jpg)
PROBLEM
○ DEVELOPERS / ARCHITECTS ARE ONLY THINKING ABOUT THE
FRAMEWORK (DB, ORM, CACHING)
○ MOST OF OUR DEVELOPMENT TIME IS SPENT WRITING PLUMPING
FOR THE FRAMWORK INSTEAD OF REAL BUSINESS LOGIC
○ THE MEANING OF OOP IS LOST
![Page 6: Domain Driven Design](https://reader034.fdocuments.net/reader034/viewer/2022051816/546d47b7af795963268b4858/html5/thumbnails/6.jpg)
WHAT
○ DOMAIN DRIVEN DESIGN IS ABOUT MAPPING BUSINESS DOMAIN
CONCEPT INTO CODE
WHY
○ TO CREATE SOFTWARE THAT REFLECT THE BUSINESS RATHER
THAN THE FRAMEWORK
DOMAIN DRIVEN DESIGN
![Page 7: Domain Driven Design](https://reader034.fdocuments.net/reader034/viewer/2022051816/546d47b7af795963268b4858/html5/thumbnails/7.jpg)
DOMAIN DRIVEN ARCHITECTURE
CONTROLLER
SERVICE
DOMAIN
DAO
DATABASE
FRAMEWORK
APPLICATION
DOMAIN
DATA ACCESS /
PERSISTENCE
DATA STORE
● HTTP
● SESSION MANAGEMENT
● RPC
● PERSISTENCE
● CACHING
● SECURITY
● MESSAGING
● ALL LAYERS SUPPORT POPO BASED DESIGN
● CONTROLLERS AND SERVICES ARE
CONSUMERS OF DOMAIN OBJECTS
● BUSINESS LOGIC ONLY IN DOMAIN OBJECTS
● NO DIRECT ACCESS TO DAO EXCEPT FROM
DOMAIN OBJECT
● DOMAIN FIRST, FRAMEWORK SECOND
● FRAMEWORK CONCERNS ARE
IMPLEMENTED BY DI
![Page 8: Domain Driven Design](https://reader034.fdocuments.net/reader034/viewer/2022051816/546d47b7af795963268b4858/html5/thumbnails/8.jpg)
ADVANTAGES
○ PROMOTES HIGH COHESION AND LOW COUPLING
○ EASY TO TEST DOMAIN COMPONENTS
○ BUSINESS (DOMAIN) LOGIC IS ISOLATED FROM NON-DOMAIN AND
FRAMEWORK CODE
○ ADDING / CHANGING SERVICES DOES NOT INFLUENCE THE
DOMAIN OR OTHER SERVICES
![Page 9: Domain Driven Design](https://reader034.fdocuments.net/reader034/viewer/2022051816/546d47b7af795963268b4858/html5/thumbnails/9.jpg)
DEVELOPMENT IMPACT
EFFORT TO
ENHANCE /
MAINTAIN
COMPLEXITY TO IMPLEMENT
SOURCE: PATTERNS OF ENTERPRISE APPLICATION ARCHITECTURE, MARTIN FOWLER
TRANSACTION
SCRIPTS
TABLE MODULES
DOMAIN MODEL
![Page 10: Domain Driven Design](https://reader034.fdocuments.net/reader034/viewer/2022051816/546d47b7af795963268b4858/html5/thumbnails/10.jpg)
HOW TO DO DDD
THE UBIQUITOUS LANGUAGE
![Page 11: Domain Driven Design](https://reader034.fdocuments.net/reader034/viewer/2022051816/546d47b7af795963268b4858/html5/thumbnails/11.jpg)
UBIQUITOUS LANGUAGE
○ SHARED TEAM LANGUAGE (DEVELOPERS AND DOMAIN EXPERTS)
○ UBIQUITOUS IS NOT AN ATTEMPT TO DESCRIBE ENTERPRISE-WIDE
DOMAIN LANGUAGE
○ ONE UBIQUITOUS LANGUAGE PER BOUNDED CONTEXT (CODE
BASE)
○ IF YOU TRY TO APPLY A SINGLE UBIQUITOUS LANGUAGE TO AN
ENTIRE ENTERPRISE, YOU WILL FAIL
![Page 12: Domain Driven Design](https://reader034.fdocuments.net/reader034/viewer/2022051816/546d47b7af795963268b4858/html5/thumbnails/12.jpg)
public function chargeCustomer(ChargecodeData $chargecode, Transaction $transaction) {
if($chargecode->getEmail() === $transaction->getCustomerEmail()
&& $transaction->getCustomerCreditCardExpiration > date(‘Y-m’)
&& in_array($transaction->getStatus(), [‘SALE’, ‘REBILL’, ‘AUTHORISE’])
&& $chargecode->isUsed() === false) {
// Do charge
}
throw new ChargeCustomerException();
}
/**
* @Inject
* @var ChargeCodeValidationPolicy
*/
protected $oneClickPolicy;
public function chargeCustomer(ChargecodeData $chargecode, Transaction $transaction) {
if($this->oneClickPolicy->isAllowed($chargecode, $transaction)) {
// Do charge
}
throw new ChargeCustomerException();
}
![Page 13: Domain Driven Design](https://reader034.fdocuments.net/reader034/viewer/2022051816/546d47b7af795963268b4858/html5/thumbnails/13.jpg)
DOMAIN OBJECTS ARE INSTANCES OF REAL ENTITIES THAT HOLD THE
BUSINESS LOGIC.
DOMAIN OBJECTS
![Page 14: Domain Driven Design](https://reader034.fdocuments.net/reader034/viewer/2022051816/546d47b7af795963268b4858/html5/thumbnails/14.jpg)
MAIN ELEMENTS OF DDD
![Page 15: Domain Driven Design](https://reader034.fdocuments.net/reader034/viewer/2022051816/546d47b7af795963268b4858/html5/thumbnails/15.jpg)
○ DESIGN A CONCEPT AS AN ENTITY WHEN YOU CARE ABOUT ITS
INDIVIDUALITY, WHEN DISTINGUISHING IT FROM ALL OTHER
OBJECTS IN A SYSTEM IS A MANDATORY CONSTRAINT
(CUSTOMER, MEMBERSHIP)
○ THE ENTITY SHOULD NOT BE BOUND TO ANY FRAMEWORK (ORM),
IT SHOULD BE A PLAIN OLD PHP OBJECT (POPO)
ENTITIES
![Page 16: Domain Driven Design](https://reader034.fdocuments.net/reader034/viewer/2022051816/546d47b7af795963268b4858/html5/thumbnails/16.jpg)
/** @Entity */class Membership{
/** @Id @Column(type="integer") @GeneratedValue */
private $id;
/** @Column(type="string") */
private $status;
/** @ManyToOne(targetEntity="Customer") */
private $customer;
/** @OneToMany(targetEntity="Transaction", mappedBy="membership") */
private $transactions;
public function __construct {
$this->transactions = new ArrayCollection();
}
public function getCustomer() { return $this->customer; }
public function getTransactions() { return $this->transactions;}}POPO
![Page 17: Domain Driven Design](https://reader034.fdocuments.net/reader034/viewer/2022051816/546d47b7af795963268b4858/html5/thumbnails/17.jpg)
VALUE OBJECT
○ STRIVE TO MODEL USING VALUE OBJECTS INSTEAD OF ENTITIES
WHEREVER POSSIBLE
○ IMMUTABLE, AFTER THE OBJECT HAS BEEN INSTANTIATED, NONE
OF ITS METHODS WILL CAUSE ITS STATE TO CHANGE
○ INSTEAD OF CHANGING THE ATTRIBUTES, WOULD OBJECT
REPLACEMENT WORK INSTEAD?
![Page 18: Domain Driven Design](https://reader034.fdocuments.net/reader034/viewer/2022051816/546d47b7af795963268b4858/html5/thumbnails/18.jpg)
$factory = new ChargeCodeGenerationDataFactory();
$chargeCodeData = $factory->generateFromArray($data);
class ChargeCodeGenerationData{
private $transactionId;
private $emailAddress;
private $accountId;
public function __construct($transactionId, $emailAddress, $accountId) {
$this->transactionId = $transactionId;
$this->emailAddress = $emailAddress;
$this->accountId = $accountId;
}
public function toArray() { return [‘transactionId’ => $this->transactionId,
‘emailAddress’ => $this->emailAddress,
‘accountId’ => $this->accountId]; }
public function toJSON() { return json_encode($this->toArray());}}
![Page 19: Domain Driven Design](https://reader034.fdocuments.net/reader034/viewer/2022051816/546d47b7af795963268b4858/html5/thumbnails/19.jpg)
○ IN A CUSTOMER MANAGEMENT CONTEXT CUSTOMER SHOULD BE
AN ENTITY
○ IN A MEMBERSHIP CONTEXT CUSTOMER SHOULD BE A VALUE
OBJECT
VO BASED ON BOUNDED CONTEXT
![Page 20: Domain Driven Design](https://reader034.fdocuments.net/reader034/viewer/2022051816/546d47b7af795963268b4858/html5/thumbnails/20.jpg)
○ PROVIDES FUNCTIONALITIES FOR THE DOMAIN
○ STATELESS
○ DOMAIN SERVICES != APPLICATION SERVICES != CONTROLLER
○ DOMAIN SERVICES CAN HOST DOMAIN LOGIC
○ PERFORM A SIGNIFICANT BUSINESS PROCESS
○ TRANSFORM A DOMAIN OBJECT FROM ONE COMPOSITION TO ANOTHER
○ CALCULATE A VALUE REQUIRING INPUT FROM MORE THAN ONE DOMAIN OBJECT
SERVICES
![Page 21: Domain Driven Design](https://reader034.fdocuments.net/reader034/viewer/2022051816/546d47b7af795963268b4858/html5/thumbnails/21.jpg)
class OneClickService{
/**
* @var ChargecodeAuthcodeValidatorInterface
*/
protected $_dataAccessor; /**
* @var \Tc_Bz_HashGenerator_Interface
*/
protected $_hashGenerator;
/**
* @var ChargecodeAuthcodeValidationResponseDataFactoryInterface
*/
protected $_factoryResponceValidate;
public function __construct($dataAccessor, $hashGenerator, $factory) { $this-
>_dataAccessor = $dataAccessor;
$this->_hashGenerator = $hashGenerator;
$this->_factoryResponceValidate = $factory;
}
/**
* validate chargecode By Authcode
*
* @param ChargecodeAuthcodeDataInterface $chargecodeAuthcodeValidationData
* @return ChargecodeAuthcodeValidationResponseData
* @throws ChargecodeAuthcodeValidationDataException
*/
public function validateChargecodeByAuthcode(ChargecodeAuthcodeDataInterface $data)
{
$decryptedData = $this->_hashGenerator->decipher( $data>getCryptedString());
if ($decryptedData === false) {
throw new ChargecodeAuthcodeValidationDataException('Not decipherable');
}
$this->_validateEmailLinkedToAuthcode($data->getEmailAddress(),
$data->getTransactionId());
$this->_validateCustomCodeIdLinkedToEnterprise($data->getAccountIdDestination(),
$data->getEnterpriseId());
$this->_validateCustomerIs1Clickable($data->getTransactionId());
$this->_validateCodeNotUsed($data->getAccountIdDestination(),
$data->getEmailAddress());
$reponseData = $data->toArray();
$reponseData['chargecode'] = $decryptedData['hash'];
$response = $this->_factoryResponseValidate->generateResponse($reponseData);
return $response;
}
}
![Page 22: Domain Driven Design](https://reader034.fdocuments.net/reader034/viewer/2022051816/546d47b7af795963268b4858/html5/thumbnails/22.jpg)
○ GROUP OF ASSOCIATED ENTITIES AND VALUE OBJECTS TREATED
AS A UNIT FOR THE PURPOSE OF DATA EXCHANGE
○ ENTITY AS ROOT ELEMENT
○ ONLY THE ROOT IS OBTAINED THROUGH QUERIES
○ THE ENTITY IS RESPONSIBLE FOR MAINTAINING THE INVARIANCE
○ DELETE OPERATION MUST REMOVE EVERYTHING WITHIN THE
AGGREGATE BOUNDARY AT ONCE (CASCADE DELETE)
AGGREGATES
![Page 23: Domain Driven Design](https://reader034.fdocuments.net/reader034/viewer/2022051816/546d47b7af795963268b4858/html5/thumbnails/23.jpg)
AGGREGATE
MEMBERSHIP
CUSTOMER
CREDIT CARD EMAILTRANSACTION
EMAILCREDIT CARDTRANSACTION
TRANSACTION
SITE
![Page 24: Domain Driven Design](https://reader034.fdocuments.net/reader034/viewer/2022051816/546d47b7af795963268b4858/html5/thumbnails/24.jpg)
○ PROVIDES ENCAPSULATION FOR OBJECT / AGGREGATE CREATION
○ PRODUCES AN OBJECT IN A CONSISTENT STATE
FACTORIES
![Page 25: Domain Driven Design](https://reader034.fdocuments.net/reader034/viewer/2022051816/546d47b7af795963268b4858/html5/thumbnails/25.jpg)
class ChargecodeAuthcodeGenerationResponseDataFactory
{
/**
* Factory method to generate chargecode validation data by authcode
*
* @param array $data Data used to generate
* @throws ChargecodeAuthcodeValidationDataException
* @return ChargecodeAuthcodeGenerationResponseData
*/
public function generateFromArray(array $data)
{
$this->_validateParameters($data);
$chargecodeData = $this->_generateDataAccessObject($data);
$data = $this->_unsetUnusedParameters($data);
$chargecodeData->setParams($data);
return $chargecodeData;
}
protected function _sendException()
{
throw new ChargecodeAuthcodeGenerationResponseDataException('Could not Generate a response');
}
protected function _generateDataAccessObject(array $data)
{
return new ChargecodeAuthcodeGenerationResponseData($data['authCode'], $data['account_id_destination'], $data['email_address'],
$data['crypted_string'], null);
}
}
![Page 26: Domain Driven Design](https://reader034.fdocuments.net/reader034/viewer/2022051816/546d47b7af795963268b4858/html5/thumbnails/26.jpg)
○ PATTERN FOR RETRIEVING AND SAVING OBJECTS IN THE DB
○ SHOULD NOT BE TIED TO SPECIFIC FRAMEWORK (ORM)
○ EASY SUBSTITUTION FOR TESTING
REPOSITORIES
![Page 27: Domain Driven Design](https://reader034.fdocuments.net/reader034/viewer/2022051816/546d47b7af795963268b4858/html5/thumbnails/27.jpg)
class SubEnterpriseRepository
{
/**
* @Inject
* @var SubEnterpriseDataAccessorInterface
*/
private $_dataAccessor;
/**
* @Inject
* @var SubEnterpriseParserInterface
*/
private $_dataParsor;
/**
* @Inject
* @var SubEnterpriseFactoryInterface
*/
private $_dataFactory;
/**
* @param $account
* @return mixed
*/
public function findSubEnterpriseByAccount(Account $account)
{
$results = $this->_dataAccessor->findSubEnterpriseByAccount($account);
$parsedResults = $this->_dataParsor->parseResults($results);
return $this->_dataFactory->create($parsedResults);
}
}
![Page 28: Domain Driven Design](https://reader034.fdocuments.net/reader034/viewer/2022051816/546d47b7af795963268b4858/html5/thumbnails/28.jpg)
○ OBJECTS SHOULD NOT DEPEND ON CONCRETE CONSTRUCTOR
VARIABLES, INSTEAD TO SHOULD USE INTERFACES
○ OBJECTS SHOULD NOT HAVE TO CONFIGURE ITS INSTANCE
VARIABLES IN THE CONSTRUCTOR OR INIT FUNCTION, INSTEAD
THEY SHOULD RECEIVE THEM ALREADY PRE-CONFIGURED
DEPENDENCY INJECTION
![Page 29: Domain Driven Design](https://reader034.fdocuments.net/reader034/viewer/2022051816/546d47b7af795963268b4858/html5/thumbnails/29.jpg)
“
”
"Dependency Injection" is a 25-dollar
term for a 5-cent concept. [...]
Dependency injection means giving
an object its instance variables. [...].
- James Shore
![Page 30: Domain Driven Design](https://reader034.fdocuments.net/reader034/viewer/2022051816/546d47b7af795963268b4858/html5/thumbnails/30.jpg)
PHP-DI
class SubEnterpriseRepository
{
/**
* @Inject
* @var SubEnterpriseDataAccessorInterface
*/
private $_dataAccessor;
/**
* @Inject
* @var SubEnterpriseParserInterface
*/
private $_dataParsor;
/**
* @Inject
* @var SubEnterpriseFactoryInterface
*/
private $_dataFactory;
/**
* @param $account
* @return mixed
*/
public function findSubEnterpriseByAccount(Account $account)
{
$results = $this->_dataAccessor->findSubEnterpriseByAccount($account);
$parsedResults = $this->_dataParsor->parseResults($results);
return $this->_dataFactory->create($parsedResults);
}
}
// Load the container
$container = new DI\Container();
$container->addDefinitionsByFile(new ArrayDefinitionFile(‘di.php’));
// Create the object
$repository = new SubEnterpriseRepository();
// Inject the dependencies
$container->injectOn($repository);
// di.php
return [
‘SubEnterpriseDataAccessorInterface’
=> [ ‘class’ : ‘DoctrineSubEnterpriseAccessor’,
‘methods’ => [
‘setHydrator’ => DOCTRINE_CORE::HYDRATE_SCALAR
]
],
‘SubEnterpriseParserInterface’
=> new SubEnterpriseDoctrineToArrayParser(),
‘SubEnterpriseFactoryInterface’
=> new SubEnterpriseResultFactory()
];
![Page 31: Domain Driven Design](https://reader034.fdocuments.net/reader034/viewer/2022051816/546d47b7af795963268b4858/html5/thumbnails/31.jpg)
PHP-DI-ZF1
/**
* Initialize the dependency injection container
*/
protected function _initDependencyInjection()
{
$this->bootstrap('DependencyInjectionContainerResource');
$container = $this->getResource('DependencyInjectionContainerResource');
$dispatcher = new \DI\ZendFramework1\Dispatcher();
$dispatcher->setContainer($container);
$frontController = Zend_Controller_Front::getInstance();
$frontController->setDispatcher($dispatcher);
}
class Tc_Application_Resource_DependencyInjectionContainerResource extends
Zend_Application_Resource_ResourceAbstract
{
public function init()
{
$this->_container = new \DI\Container();
foreach($this->_definitionFilePath as $DIResourceFile) {
$file = $this->_loadDefinitionFile(realpath($DIResourceFile));
$this->_container->addDefinitionsFromFile($file);
}
return $this->_container;
}
private function _loadDefinitionFile($DIResourceFile)
{
$file = null;
if (0 === substr_compare($DIResourceFile, 'php', -3, 3, true)) {
$file = new \DI\Definition\FileLoader\ArrayDefinitionFileLoader($DIResourceFile);
}
if (0 === substr_compare($DIResourceFile, 'yml', -3, 3, true)) {
$file = new \DI\Definition\FileLoader\YamlDefinitionFileLoader($DIResourceFile);
}
if (0 === substr_compare($DIResourceFile, 'json', -4, 4, true)) {
$file = new \DI\Definition\FileLoader\JsonDefinitionFileLoader($DIResourceFile);
}
if($file === null) {
throw new Gamma_Application_Resource_Exception('Invalid Definition File Type');
}
return $file;
}
![Page 32: Domain Driven Design](https://reader034.fdocuments.net/reader034/viewer/2022051816/546d47b7af795963268b4858/html5/thumbnails/32.jpg)
PHP-DI-ZF1
class Direct_FollowController extends Zend_Controller_Action
{
/**
* @Inject(lazy=true)
* @var \Tc\Service\ChargeCodeService
*/
private $_oneClickService;
/**
* @Inject(lazy=true)
* @var \Tc\ChargeCode\Data\ChargecodeAuthcodeGenerationDataFactory
*/
private $_factory;
public function generateChargeCodeByAuthcodeAction()
{
$request = $this->getRequest();
$this->getResponse()->setHeader('Content-Type', 'application/json', true);
try {
$chargeCodeGenerationData = $this->_factory->generate($request->getParams());
$this->view->answer = $this->_oneClickService->generate($chargeCodeGenerationData);
$this->render('generate-charge-code');
} catch (\Tc\ChargeCode\Data\Exception\ChargeCodeGenerationDataException $chargeCodeException) {
$this->view->requiredParameters = $chargeCodeException;
$this->render('charge-code-generation-authcode-invalid-parameters');
} catch (\Tc\ChargeCode\Data\Exception\ChargecodeAuthcodeGenerationResponseDataException $chargeCodeException) {
$this->view->requiredParameters = $chargeCodeException;
$this->render('charge-code-generation-authcode-invalid-parameters');
}
}
![Page 33: Domain Driven Design](https://reader034.fdocuments.net/reader034/viewer/2022051816/546d47b7af795963268b4858/html5/thumbnails/33.jpg)
DOMAIN & SUB-DOMAIN
THE HEART OF DDD
![Page 34: Domain Driven Design](https://reader034.fdocuments.net/reader034/viewer/2022051816/546d47b7af795963268b4858/html5/thumbnails/34.jpg)
DOMAIN vs DOMAIN MODEL
○ THE DOMAIN IS THE PROBLEM TO BE ADDRESSED IN SOFTWARE
○ A DOMAIN MODEL IS THE REPRESENTATION OF IN CODE OF THE
SOLUTION FOR THE DOMAIN PROBLEM
○ HAS TO BE CREATED WITH THE COOPERATION OF DEVELOPERS
AND DOMAIN EXPERTS
○ THE GOAL OF DOMAIN DRIVEN DESIGN IS TO CREATE OBJECT IN
CODE THAT REFLECT THE DOMAIN
![Page 35: Domain Driven Design](https://reader034.fdocuments.net/reader034/viewer/2022051816/546d47b7af795963268b4858/html5/thumbnails/35.jpg)
○ DOMAIN CAN BE DECOMPOSED INTO SUB-DOMAINS (PRODUCTS,
BILLING, MEMBERSHIP)
○ SUB-DOMAIN SPLIT THE DOMAIN INTO DIFFERENT UNIQUE
SECTIONS
○ BOUNDED CONTEXT SPLIT THE CODE INTO DIFFERENT CODE
BASES
○ SUB-DOMAIN CAN BE IMPLEMENTED BY MULTIPLE BOUNDED
CONTEXTS (MEMBERSHIP AND MEMBERSHIP REBILL)
SUB-DOMAIN vs BOUNDED CONTEXT
![Page 36: Domain Driven Design](https://reader034.fdocuments.net/reader034/viewer/2022051816/546d47b7af795963268b4858/html5/thumbnails/36.jpg)
“
”
ORGANIZATIONS WHICH DESIGN
SYSTEMS ARE CONSTRAINED TO
PRODUCE DESIGNS WHICH ARE
COPIES OF THE COMMUNICATION
STRUCTURES OF THESE
ORGANIZATIONS- Melvin Conway
![Page 37: Domain Driven Design](https://reader034.fdocuments.net/reader034/viewer/2022051816/546d47b7af795963268b4858/html5/thumbnails/37.jpg)
SUB-DOMAIN BOUNDARIES ARE DETERMINED IN PART BY THE
COMMUNICATION STRUCTURES WITHIN AN ORGANIZATION
CONWAY’S LAW
![Page 38: Domain Driven Design](https://reader034.fdocuments.net/reader034/viewer/2022051816/546d47b7af795963268b4858/html5/thumbnails/38.jpg)
![Page 39: Domain Driven Design](https://reader034.fdocuments.net/reader034/viewer/2022051816/546d47b7af795963268b4858/html5/thumbnails/39.jpg)
○ CODE BASE FOR DOMAIN MODEL CONTEXT
○ EVERY MODEL’S PROPERTIES AND OPERATIONS HAS SPECIAL
MEANING WITHIN THE SPECIFIC CONTEXT
BOUNDED CONTEXTS
![Page 40: Domain Driven Design](https://reader034.fdocuments.net/reader034/viewer/2022051816/546d47b7af795963268b4858/html5/thumbnails/40.jpg)
ENTITYVALUE OBJECT
![Page 41: Domain Driven Design](https://reader034.fdocuments.net/reader034/viewer/2022051816/546d47b7af795963268b4858/html5/thumbnails/41.jpg)
CONTEXT MAPPING
○ PARTNERSHIP○ SUCCEED OR FAIL TOGETHER
○ COORDINATED PLANNING
○ JOINT MANAGEMENT OF
INTEGRATION
○ SCHEDULED COMPLETION
○ SHARED KERNEL○ INTIMATE INTERDEPENDENCIES
○ KEEP IT SMALL
○ CAN’T BE CHANGED WITHOUT
CONSULTATION
○ CUSTOMER-SUPPLIER○ UPSTREAM / DOWNSTREAM
RELATIONSHIP
○ DOWNSTREAM PRIORITIES FACTOR
INTO UPSTREAM PLANNING
○ NEGOTIATED SCHEDULE
○ CONFORMIST○ UPSTREAM / DOWNSTREAM
RELATIONSHIP
○ UPSTREAM HAS NO MOTIVATION TO
PROVIDE FOR DOWNSTREAM
![Page 42: Domain Driven Design](https://reader034.fdocuments.net/reader034/viewer/2022051816/546d47b7af795963268b4858/html5/thumbnails/42.jpg)
CONTEXT MAPPING
○ ANTICORRUPTION LAYER○ TRANSLATION LAYER
○ LAYER TRANSLATES IN ONE OR BOTH
DIRECTIONS BETWEEN THE TWO
MODELS
○ OPEN HOST SERVICE○ SOA
○ PROTOCOL TO GIVE ACCESS TO
YOUR SUBSYSTEM
○ PUBLISHED LANGUAGE○ WELL-DOCUMENTED SHARED
LANGUAGE
○ SEPARATE WAYS○ COMPLETELY CUT LOOSE FROM
EACH OTHER
○ INTEGRATION IS EXPENSIVE WITH
SMALL BENEFITS
○ BIG BALL OF MUD○ MIXED MODELS
○ INCONSISTENT BOUNDARIES
○ DRAW A BOUNDARY AROUND THE
MESS
○ DO NOT TRY TO APPLY
SOPHISTICATED MODELING
![Page 43: Domain Driven Design](https://reader034.fdocuments.net/reader034/viewer/2022051816/546d47b7af795963268b4858/html5/thumbnails/43.jpg)
“
”
Any 3rd party system
that I have to integrate
with, was written by
a drunken monkey
typing with his feet
- Oren Eini
![Page 44: Domain Driven Design](https://reader034.fdocuments.net/reader034/viewer/2022051816/546d47b7af795963268b4858/html5/thumbnails/44.jpg)
SUB-DOMAIN
SUB-DOMAIN
ANTICORRUPTION
LAYER THAT
TRANSLATES
USER/ROLES
BETWEEN SUB-
DOMAINS
![Page 45: Domain Driven Design](https://reader034.fdocuments.net/reader034/viewer/2022051816/546d47b7af795963268b4858/html5/thumbnails/45.jpg)
“
”
Any fool can write code that a
computer can understand. Good
programmers write code that humans
can understand.
- Martin Fowler
![Page 46: Domain Driven Design](https://reader034.fdocuments.net/reader034/viewer/2022051816/546d47b7af795963268b4858/html5/thumbnails/46.jpg)
REFERENCES
DOMAIN-DRIVEN DESIGN
BY ERIC EVANS
IMPLEMENTING DOMAIN-DRIVEN
DESIGN
BY VAUGHN VERNON