Top Banner
Relentless Refactoring Strategic improvement through Domain-Driven Design Mark Rickerby
45

Relentless Refactoring

Jan 13, 2015

Download

Technology

Mark Rickerby

 
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Relentless Refactoring

Relentless RefactoringStrategic improvement through 

Domain-Driven Design

Mark Rickerby

Page 2: Relentless Refactoring

@maetlmaetl.netgithub.com/maetl

Page 3: Relentless Refactoring

Introducing the most popular software architecture in the world...

Page 4: Relentless Refactoring

¶ Big Ballof Mud

Page 5: Relentless Refactoring
Page 6: Relentless Refactoring

The year 2000 in web softwareContinuum of architectural confusion

brutalist structure

organic miasma

procedural PHP, Perl, ASP, etc...

spaghetti code jungle 

J2EE frameworkstandards

indirection and bloat

Page 7: Relentless Refactoring

The year 2000 in web softwareContinuum of architectural confusion

brutalist structure

organic miasma

Page 8: Relentless Refactoring

“Elegance is not a dispensable luxury but a

factor that decides between success and

failure.”

Edsger Dijkstra

Page 9: Relentless Refactoring

Design patternsEventually developers figured it out

Page 10: Relentless Refactoring

Design patternsAn explosion of web frameworks followed

Page 11: Relentless Refactoring

Convention over configurationGeneric Model-View-Controller separation

app/controllers/CategoriesController.phpapp/controllers/ProductsController.phpapp/models/Category.phpapp/models/Product.phpapp/templates/categories/*app/templates/products/*

Page 12: Relentless Refactoring

What is the model?Are these data objects or domain objects?

app/controllers/CategoriesController.phpapp/controllers/ProductsController.phpapp/models/Category.phpapp/models/Product.phpapp/templates/categories/*app/templates/products/*

Page 13: Relentless Refactoring

Anemic modelsThe result of leaky abstractions

— the app/models convention is a sensible default for basic CMS driven websites

— Active Record fools developers into thinking that persistence is the core concept of the ‘M’ in MVC

Page 14: Relentless Refactoring

Eventual inconsistencyIf a shortcut exists it will be used

— when the software model does not capture rich relationships and behavior, controllers and templates expedite the process of adding new functionality

Page 15: Relentless Refactoring

Eventual inconsistencyFramework defaults become inexact

app/controllers/CategoriesController.phpapp/controllers/CheckoutController.phpapp/controllers/ProductsController.phpapp/models/Category.phpapp/models/Product.phpapp/templates/categories/*app/templates/checkout/*app/templates/products/*

Page 16: Relentless Refactoring

Ad-hoc developmentWhen features outgrow the framework

— when in doubt, developers add new behavior to existing methods

— bug-fixes and knowledge about system behavior accumulates in procedural code

Page 17: Relentless Refactoring

Metaphor shearLoss of cohesion; design disorientation

Page 18: Relentless Refactoring

Ad-hoc duplicationReliance on utility functions for common tasks

$units = $config->defaultWeightUnits;$w = explode(' ', $product->weight);

if ($w[1] != 'lbs') {   $weight = convertWeight(                $w[0], $units, 'lbs'              );} else {   $weight = $w[0];}

 

Page 19: Relentless Refactoring

Ad-hoc behaviourIndependent services tangled inside existing interface

class Product extends ActiveRecord {

  public function create($imported=false) {     if ($imported) {      // edge case when the      // product is created from      // a bulk import    }  }   }

Page 20: Relentless Refactoring
Page 21: Relentless Refactoring

¶ Domain Driven Design

Page 22: Relentless Refactoring

Domain Driven DesignEric Evans, 2004

really a book about refactoring

Page 23: Relentless Refactoring

Discover missing conceptsRefactoring towards deeper insight

— focus on conceptual integrity

— be prepared to look at things in a different way

— constantly refine the language used to describe the software domain

Page 24: Relentless Refactoring

A unified languageNot just a collection of singular entities

$ mv app/models app/model

 

Page 25: Relentless Refactoring

A unified languageBuilding blocks for a fine grained model

Entity~ persistent ‘noun’ with identity and stateeg: product, category

Value~ atomic object with no unique identityeg: price, currency, weight

Service~ stateless ‘verb’, action or process

Aggregate~ a cluster of related objects

Page 26: Relentless Refactoring

Ad-hoc duplicationReliance on utility functions for common tasks

$units = $config->defaultWeightUnits;$w = explode(' ', $product->weight);

if ($w[1] != 'lbs') {   $weight = convertWeight(                $w[0], $units, 'lbs'              );} else {   $weight = $w[0];}

Page 27: Relentless Refactoring

Small values Immutable objects that model basic domain concepts

app/model/Product.phpapp/model/Weight.php

$weight = $product->weight->lbs();

 

Page 28: Relentless Refactoring

Ad-hoc behaviourIndependent services tangled inside existing interface

class Product extends ActiveRecord {

   public function create($imported=false)   {      if ($imported) {       // edge case when the       // product is created from       // a bulk import     }   }     } 

Page 29: Relentless Refactoring

Service layerBreak out standalone tasks into transactional interface

class ProductImporter extends BulkImporter {      public function importProduct($product)   {      // no longer an edge case   }}

Page 30: Relentless Refactoring

Aggregate rootsDivide complex entities into a more granular model

app/model/Attribute.phpapp/model/AttributeValue.phpapp/model/Product.phpapp/model/ProductAttribute.phpapp/model/ProductDetails.phpapp/model/Sku.php

class Product extends Aggregate {}

Page 31: Relentless Refactoring

Benefits of a richer modelWhy use object oriented design anyway?

— easier to localize changes when behavior and data are close together

— negotiate complexity with precise language

— objects have a single responsibility; easier to understand and maintain

Page 32: Relentless Refactoring

Design is continuousChange code based on improved understanding

— models are dynamic;always changing and growing

— models are explanatory;define domain knowledge in code

Page 33: Relentless Refactoring

AmbiguitiesContradictory concepts in the domain language

— avoid trying to build a monolithic model that captures every aspect of the domain

— tackle ambiguity by grouping the model into Bounded Contexts

Page 34: Relentless Refactoring

Model namespaceGrouping based on pattern types

app/model/collections/ProductList.phpapp/model/entities/Product.phpapp/model/services/ShippingProvider.phpapp/model/services/TaxRate.phpapp/model/values/Weight.phpapp/model/values/Price.php

 

Page 35: Relentless Refactoring

Model namespaceGrouping based on context boundaries

app/model/Invoicing/TaxRate.phpapp/model/Shipping/Provider.phpapp/model/Storefront/Price.phpapp/model/Storefront/Product.phpapp/model/Storefront/ProductList.phpapp/model/Storefront/Weight.php

 

Page 36: Relentless Refactoring

Shared coreExtract common behaviour into a shared context

app/model/Core/Price.phpapp/model/Core/Weight.phpapp/model/Core/Product.phpapp/model/Invoicing/TaxRate.phpapp/model/Shipping/Provider.phpapp/model/Storefront/ProductList.php

Page 37: Relentless Refactoring

Context mapDefine relationships between bounded contexts

Page 38: Relentless Refactoring

HomonymsOverloaded concepts in the domain language

— the same word is used to describe many different concepts

— the same concept has many different responsibilities

Page 39: Relentless Refactoring

Bounded contextsAllow ambiguous concepts to co-exist

app/model/Core/Price.phpapp/model/Core/Weight.phpapp/model/Core/Product.phpapp/model/Invoicing/TaxRate.phpapp/model/Shipping/Product.phpapp/model/Shipping/Provider.phpapp/model/Storefront/Product.phpapp/model/Storefront/ProductList.php

Page 40: Relentless Refactoring

Anticorruption layerIsolating adapter between incompatible contexts

Page 41: Relentless Refactoring

Refactoring is designChanging the structure of existing code

Page 42: Relentless Refactoring

Refactoring is designChanging the structure of component boundaries

Page 43: Relentless Refactoring

Application boundariesRefactoring patterns for evolving architecture

Introduce Strangler~new abstraction that overtakes the host system like a strangling vine

Extract Service~spawn a separate application by extracting a service from the original system

Page 44: Relentless Refactoring

SummaryRelentless improvement

Separate infrastructure from the model

Use precise language to define domain concepts

Model complex behaviour in bounded contexts

Page 45: Relentless Refactoring

ThanksMark Rickerby, 2011