Introduction to Domain driven design (LaravelBA #5)

Post on 19-Nov-2014

180 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

Introduction to Domain driven design, given by @GuiWoda at #LaravelBA on sept 17, 2014

Transcript

Domain Driven Design

Ubiquitous Language

UbiquitousLanguage@Fowler's blog

Ubiquitous LanguageThat’s all there is to it

Ubiquitous LanguageThat’s all there is to it

Questions?

Client (Domain expert)

Project Manager Developer

We need to add a new security policy to our

accounts. Our customers can’t have more than two

active offers per billing term.

We need to restrict promotions. A user cannot

have more than two promotions per month.

public function validate(User $user){ // … other crazy validations

if (count ($user->getPromotions()) > 2) throw new ValidationException( “User can’t have more than 2 promotions per month” );

// … continue with crazy validations}

Favor model language over translations

Client (Domain expert)

Project Manager Developer

We need to add a new security policy to our

accounts. Our customers can’t have more than two

active offers per billing term.

public function validate(Account $account){ // … other crazy validations

if (! $account->satisfies( new ActiveOffersPerBillingTermSecurityPolicy )) throw new ValidationException( “Account did not satisfy the active offers security policy” );

// … continue with crazy validations}

ActiveOffersPerBillingTermSecurityPolicy

… really?TOO MUCH CODE!

I WON’T TYPE THAT!!!11

Semantics

SemanticsActiveOffersPerBillingTermSecurityPolicy means something

in the MODEL LANGUAGE

count($user->getPromotions()) > 2 does not convey this knowledge

SemanticsActiveOffersPerBillingTermSecurityPolicy means something

in the MODEL LANGUAGE

count($user->getPromotions()) > 2 does not convey this knowledge

=> MAKE IMPLICIT BUSINESS RULES EXPLICIT

Favor model language over translations

When a domain expert (client) feels something’s wrong with the model language, you’ll know something’s wrong with the domain model.

Client (Domain expert)

Project Manager Developer

When we talk about a billing term, we need to consider if the customer is billed on a

monthly or yearly basis.

| class ActiveOffersPerBillingTermSecurityPolicy | { | protected $maxOffers = 2; | | public function isSatisfiedBy(Account $account) | { | return count(- | $account->getMonthlyOffers()+ | $account->getOffersForBillingTerm() | ) < $this->maxOffers; | }

Domain Knowledge

Domain KnowledgeFocus your efforts in building a clear domain,

specific to your client’s needs

Knowledge crunching

Client (Domain expert)

Project Manager Developer

class LongOverdueCustomerContactCommand{ public function execute() { $customers = Customer::where( ‘account.balance’, ‘<’, 0 )->get();

foreach ($customers as $customer) $this->sendRefinanceEmail($customer); }}

We need to contact long overdue customers to refinance their debt.

Client (Domain expert)

Project Manager Developer

class LongOverdueCustomerContactCommand{ public function execute() { $customers = Customer::where( ‘account.balance’, ‘<’, 0 )->get();

foreach ($customers as $customer) $this->sendRefinanceEmail($customer); }}

We need to contact long overdue customers to refinance their debt.

Client (Domain expert)

Project Manager Developer

We need to contact long overdue customers to refinance their debt.

What is the difference between a regular customer, an overdue customer and a

long overdue customer?

Client (Domain expert)

Project Manager Developer

class CustomerRepository{ public function findOverdue() { return Customer::where(‘account.balance’, ‘<’, 0) ->get(); }

public function findLongOverdue() { // Write more complex query logic for this one... }}

Overdue is straightforward, customers in debt right now.

Long overdue customers are the ones that have been overdue over the last 3

billing terms, at the end of each billing term.

Knowledge crunchingKnowledge crunching deepens the domain

model, and brings better understanding

But… How?

Domain-orientedDesign Patterns

class AccountsController{ public function index() { $accounts = Account::all();

return View::make(‘accounts.index’, [ ‘accounts’ => $accounts ]); }}

class AccountsController{ public function index() { $accounts = Account::all();

return View::make(‘accounts.index’, [ ‘accounts’ => $accounts ]); }}

EvansClassification@Fowler's blog

Entities

EntitiesObjects with an identity

LifespanUnique criteria

ValueObjects

ValueObjectsDefined by their attributes

Aggregates

AggregatesCluster of domain objectsTransactional coherence

Services

ServicesDomain coordinators

Define actions

Repositories

RepositoriesData access abstraction

Factories

FactoriesObject creation

Domain Events

Domain EventsObjects that represent significant domain

events

Domain-orientedArchitecture

Layered Architecture

Layered Architecture

?

Hexagonal Architecture

Hexagonal Architecture

?

Domain-orientedArchitecture

Isolate your domain model from specific application needs:

UI - Persistence - External Services - Application workflow - etc...

So… What’s the point?

It’s not about writing code

It’s not about writing codeThat’s the easy part… right?

It’s not about writing codeIt’s about understanding what needs to be

solved before starting to code

Creating a language which makes conversations

between domain experts and developers possible without

misinterpretations

Creating a language which makes conversations

between domain experts and developers possible without

(so many) misinterpretations

● Eric Evans, “Domain-Driven Design: Tackling Complexity in the Heart of Software”

● Vaughn Vernon, “Implementing Domain-Driven Design”

● Martin Fowler, “Patterns of Enterprise Application Architecture”

● dddcommunity.org | Domain Driven Design Community

● -http://domainlanguage.com/ddd/reference/DDD_Reference_2011-01-31.pdf

● -http://www.lmgtfy.com/?q=Domain+Driven+Design

top related