Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
EagerDesign
by @_md
♞
marcelloduarte
Introducing
marcelloduarte
@_md
#EagerDesign
agileislazy
@_md#EagerDesign
"Makethecommitmentatthelast

responsiblemoment"
Preston Smith
decide later
softwareisaboutpeople
@_md#EagerDesign
ageofexcess
@_md#EagerDesign
subtraction
@_md#EagerDesign
subtraction
@_md#EagerDesign
lawsofsubtraction
@_md
lawsofsubtraction
whatisn’ttherecanoftentrumpwhatis.thesimplest
rulescreatethemosteffectiveexperience.limiting
information...
EagerDesign
how
♞
Jumptotheproblemworthsolving
Eagerlyreplaceprimitiveswithtypes
Compose[thedomainalgebra] inside-out
Avoi...
outside-in
♞
outside-in
unittest code
refactor
acceptance
ui/controller/views
orm,libs,domainobjects
frameworkstuff(forms…)
model/view/...
events
outside-in
UI
Domain
core
Application
Infrastructure
mobileUI
port/adapter
port/adapterDB
https://pbs.twimg.com/med...
therightoutside
http://bit.ly/modellingbyexample
http://bit.ly/whencucumbersgobad
@_md#EagerDesign
{
outside-in
slow
misleading
complex
restrictscomposability
when?
EagerDesign
when
done
trivial
done

nottrivial
notdone
noidea
[based on Cynefin, Snowden 03]
@_md#EagerDesign
EagerDesign
when
done
trivial
done

nottrivial
notdone
noidea
[based on Cynefin, Snowden 03]
Outside-in
@_md#EagerDesign
EagerDesign
when
done
trivial
done

nottrivial
notdone
noidea
[based on Cynefin, Snowden 03]
EagerDesign
Outside-in
@_md#E...
EagerDesign
when
done
trivial
done

nottrivial
notdone
noidea
[based on Cynefin, Snowden 03]
EagerDesign
Outside-in
¯_(ツ)_...
Example
{
chessapp
weaddplayers
itgeneratestheschedule
wecanentertheresults
wecanseetheranking
TRIVIAL
TRIVIAL
TRIVIAL
EagerDesign...
{
domainrules
playerswillplaywitheveryotherplayer
playerscan'tplaytwiceinthesameround
everyplayermustplayineveryround
play...
HowdoIconvert

alistofthings

intoalistofuniquelists

ofuniquepairs?
Letmethink
a b c d e f g h
List of things
a b c d e f g h
List of things
Pairs
a b c d
h g f e
Pairs
a b c d
h g f e
Shift to the right
a b c d
h g f ee
We haz roundz! :o)
a b c d
h g f ee
r1 r2 r3 r4
r5 r6 r7
+ r1 r2 r3 r4
r5 r6 r7
inverse
( )
r1 r2 r3 r4
r5 r6 r7 r8
r9 r10 r11 r12
r13 r14
shuffle
( )
lawsofsubtraction
whatisn’ttherecanoftentrumpwhatis.thesimplest
rulescreatethemosteffectiveexperience.limiting
information...
#1Jumptotheproblemworthsolving
@_md#EagerDesign
http://github.com/MarcelloDuarte/phunkie
ImmList
a b c d e f g hhead
a b c d e f g htail
a b c d e f g hinit
a b c d e f g hlast
concat(
head($players),
last($players),
init(tail($players))
function shift(ImmList $players)
{
return concat(head($players),
last($players),
init(tail($players))
);
}
function shift(ImmList $players)
{
return concat(head($players),
last($players),
init(tail($players))
);
}
function round(ImmList $players)

{
$sides = $players->splitAt($players->length/2);
return $sides->_1->zip($sides->_2->rev...
function rounds(ImmList $players)

{
}
function rounds(ImmList $players, $rounds = [])

{
$rounds[] = round($players);
return count($rounds) < $players->length -...
function rounds(ImmList $players, $rounds = [])

{
$rounds[] = round($players);
return count($rounds) < $players->length -...
function rounds(ImmList $players, $rounds = [])

{
$rounds[] = round($players);
return count($rounds) < $players->length -...
function rounds(ImmList $players, $rounds = [])

{
$rounds[] = round($players);
return count($rounds) < $players->length -...
function rounds(ImmList $players, $rounds = [])

{
$rounds[] = round($players);
return count($rounds) < $players->length -...
function rounds(ImmList $players, $rounds = [])

{
$rounds[] = round($players);
return count($rounds) < $players->length -...
function schedule(ImmList $players)

{
return concat(rounds($players),

inverse(rounds($players));
}
#2Eagerlyreplaceprimitiveswithtypes
@_md#EagerDesign
“Mymathbackgroundmademerealise
thateachobjectcouldhaveseveral
algebrasassociatedwithit,andthere
couldbefamiliesofthese,and...
...Imadeupaterm"genericity"for

dealingwithgenericbehavioursina

quasi-algebraicform...
...Ididn'tlikethewaySimulaIorSimula
67didinheritance.SoIdecidedtoleave
outinheritanceasabuilt-infeatureuntilI
understoodit...
http://bit.ly/meaning-­‐of-­‐oo
type Player = string;
type Players = ImmList<Player>;

type Match = Pair<Player,Player>

type Round = ImmList<Match>;

typ...
function shift(Players $players): Players
{
return concat(head($players),
last($players),
init(tail($players))
);
}
function round(Players $players): Round

{
$sides = $players->splitAt($players->length/2);
return $sides->_1->zip($sides->...
function rounds(Players $players, $rounds = [])

: Rounds
{
$rounds[] = round($players);
return count($rounds) < $players-...
function schedule(Players $players): Rounds

{
return concat(rounds($players),

inverse(rounds($players));
}
Composethedomainalgebra
inside-out
@_md#EagerDesign
namespace MdChessScheduleGeneration;
shift(Players $players): Players

round(Players $players): Round
rounds(Players $play...
♞
Players => Schedule
Players => Rounds => Schedule
♞
Players => Round => Rounds => Schedule
♞
domainrulesaredefined
againsttypes
@_md#EagerDesign
{
domainrules
playerswillplaywitheveryotherplayer
playerscan'tplaytwiceinthesameround
everyplayermustplayineveryround
play...
richdomainmodelvs

leandomainmodel
S
S
S
S
S
S
@_md#EagerDesign
richdomain
ImmutableState
ImmutableState
ImmutableState
B B
leandomain
Laws
InterpretingServicesAgency
Example
@_md#EagerDesign
def request

def decline

def amend

def accept

def done

def request(details:JobDetails): Job

def decline(ref:JobRef): Job

def amend(details:JobDetails): Job => Option[TimeSheet...
trait JobService
{

def request(details:JobDetails): Job

def decline(ref:JobRef): Job

def amend(details:JobDetails):Job ...
trait JobService
{

def request(details:JobDetails): Job

def decline(ref:JobRef): Job

def amend(details:JobDetails):Job ...
f(a:A):M[B]



g(a:B):M[C]
f(a:A):M[B]

f(a) map g = M[M[C]]


g(a:B):M[C]
f(a:A):M[B]

join f(a) map g = M[C]


g(a:B):M[C]
f(a:A):M[B]

andThen


g(a:B):M[C]
request andThen
amend andThen
done
def execute(input:Input): Unit
path = input("path").getOrElse("specs")
loadSpecs(path) andThen
runSpecs andThen
presentRes...
what’stheeagerpoint?
@_md#EagerDesign
merging2cells!!
@_md#EagerDesign
{
3cases
samevalue
differentvalue
righthandsideis
empty
if ($this->value == $another->value) {
return Pair(Cell(),
Cell($this->value + $another->value));
} elseif ($another->isEm...
if ($this->value == $another->value) {
return Pair(Cell(),
Cell($this->value + $another->value));
} elseif ($another->isEm...
if ($this->value == $another->value) {
return Pair(Cell(),
Cell($this->value + $another->value));
} elseif ($another->isEm...
function swipe($lines)
{

return $lines->map(function ($line) {


$lineCopy = mergeLine($line);

while (!isLineMerged($lin...
EagerDesign
♞
Jumptotheproblemworthsolving
Eagerlyreplaceprimitiveswithtypes
Compose[thedomainalgebra] inside-out
Avoidmut...
marcelloduarte
@_md
#EagerDesign
Thankyou!
♞
@_md
bit.ly/inviqa-contact bit.ly/inviqa-careers
#EagerDesign
Introducing Eager Design
Introducing Eager Design
Introducing Eager Design
Introducing Eager Design
Introducing Eager Design
Introducing Eager Design
You’ve finished this document.
Download and read it offline.
Upcoming SlideShare
Empathy from Agility
Next
Upcoming SlideShare
Empathy from Agility
Next
Download to read offline and view in fullscreen.

Share

Introducing Eager Design

Download to read offline

What happens when the very frameworks, tools and patterns we cherish take the reins and forces us to focus on all the boilerplate scaffolding things, distracting us from really solving the real problems? Sometimes the outside-in approach can lead us to code that is more complex and coupled than it has to be.

Eager Design offers a fresh approach. Instead of being led by the delivery mechanisms, frameworks and patterns, we focus on the problems worth solving. Inspired by functional programming and Domain Driven Design, the principles of Eager Design helps us isolate and solve complex problems in a more focused and decouple manner.

Related Books

Free with a 30 day trial from Scribd

See all

Related Audiobooks

Free with a 30 day trial from Scribd

See all

Introducing Eager Design

  1. 1. EagerDesign by @_md ♞ marcelloduarte Introducing
  2. 2. marcelloduarte @_md #EagerDesign
  3. 3. agileislazy @_md#EagerDesign
  4. 4. "Makethecommitmentatthelast
 responsiblemoment" Preston Smith decide later
  5. 5. softwareisaboutpeople @_md#EagerDesign
  6. 6. ageofexcess @_md#EagerDesign
  7. 7. subtraction @_md#EagerDesign
  8. 8. subtraction @_md#EagerDesign
  9. 9. lawsofsubtraction @_md
  10. 10. lawsofsubtraction whatisn’ttherecanoftentrumpwhatis.thesimplest rulescreatethemosteffectiveexperience.limiting informationengagesimagination.creativitythrives underintelligentconstraints.breakistheimportant partofbreakthrough.doingsomethingisn’talways betterthandoingnothing. Matthew E. May
  11. 11. EagerDesign how ♞ Jumptotheproblemworthsolving Eagerlyreplaceprimitiveswithtypes Compose[thedomainalgebra] inside-out Avoidmutablestate #1 #2 #3 #4 @_md#EagerDesign
  12. 12. outside-in ♞
  13. 13. outside-in unittest code refactor acceptance ui/controller/views orm,libs,domainobjects frameworkstuff(forms…) model/view/controller
  14. 14. events outside-in UI Domain core Application Infrastructure mobileUI port/adapter port/adapterDB https://pbs.twimg.com/media/CHyUAukWgAA5iYS.jpg reads writes
  15. 15. therightoutside http://bit.ly/modellingbyexample http://bit.ly/whencucumbersgobad @_md#EagerDesign
  16. 16. { outside-in slow misleading complex restrictscomposability
  17. 17. when?
  18. 18. EagerDesign when done trivial done
 nottrivial notdone noidea [based on Cynefin, Snowden 03] @_md#EagerDesign
  19. 19. EagerDesign when done trivial done
 nottrivial notdone noidea [based on Cynefin, Snowden 03] Outside-in @_md#EagerDesign
  20. 20. EagerDesign when done trivial done
 nottrivial notdone noidea [based on Cynefin, Snowden 03] EagerDesign Outside-in @_md#EagerDesign
  21. 21. EagerDesign when done trivial done
 nottrivial notdone noidea [based on Cynefin, Snowden 03] EagerDesign Outside-in ¯_(ツ)_/¯ @_md#EagerDesign
  22. 22. Example
  23. 23. { chessapp weaddplayers itgeneratestheschedule wecanentertheresults wecanseetheranking TRIVIAL TRIVIAL TRIVIAL EagerDesign @_md
  24. 24. { domainrules playerswillplaywitheveryotherplayer playerscan'tplaytwiceinthesameround everyplayermustplayineveryround playersmustplaytwicewithanotherplayer @_md
  25. 25. HowdoIconvert
 alistofthings
 intoalistofuniquelists
 ofuniquepairs?
  26. 26. Letmethink
  27. 27. a b c d e f g h List of things
  28. 28. a b c d e f g h List of things Pairs a b c d h g f e
  29. 29. Pairs a b c d h g f e
  30. 30. Shift to the right a b c d h g f ee
  31. 31. We haz roundz! :o) a b c d h g f ee
  32. 32. r1 r2 r3 r4 r5 r6 r7 + r1 r2 r3 r4 r5 r6 r7 inverse ( )
  33. 33. r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 shuffle ( )
  34. 34. lawsofsubtraction whatisn’ttherecanoftentrumpwhatis.thesimplest rulescreatethemosteffectiveexperience.limiting informationengagesimagination.creativitythrives underintelligentconstraints.breakistheimportant partofbreakthrough.doingsomethingisn’talways betterthandoingnothing. Matthew E. May
  35. 35. #1Jumptotheproblemworthsolving @_md#EagerDesign
  36. 36. http://github.com/MarcelloDuarte/phunkie
  37. 37. ImmList a b c d e f g hhead a b c d e f g htail a b c d e f g hinit a b c d e f g hlast
  38. 38. concat( head($players), last($players), init(tail($players))
  39. 39. function shift(ImmList $players) { return concat(head($players), last($players), init(tail($players)) ); }
  40. 40. function shift(ImmList $players) { return concat(head($players), last($players), init(tail($players)) ); }
  41. 41. function round(ImmList $players)
 { $sides = $players->splitAt($players->length/2); return $sides->_1->zip($sides->_2->reverse()); }
  42. 42. function rounds(ImmList $players)
 { }
  43. 43. function rounds(ImmList $players, $rounds = [])
 { $rounds[] = round($players); return count($rounds) < $players->length - 1 ? rounds(shift($players), $rounds) :
 ImmList(...$rounds); }
  44. 44. function rounds(ImmList $players, $rounds = [])
 { $rounds[] = round($players); return count($rounds) < $players->length - 1 ? rounds(shift($players), $rounds) :
 ImmList(...$rounds); }
  45. 45. function rounds(ImmList $players, $rounds = [])
 { $rounds[] = round($players); return count($rounds) < $players->length - 1 ? rounds(shift($players), $rounds) :
 ImmList(...$rounds); }
  46. 46. function rounds(ImmList $players, $rounds = [])
 { $rounds[] = round($players); return count($rounds) < $players->length - 1 ? rounds(shift($players), $rounds) :
 ImmList(...$rounds); } #3Compose
  47. 47. function rounds(ImmList $players, $rounds = [])
 { $rounds[] = round($players); return count($rounds) < $players->length - 1 ? rounds(shift($players), $rounds) :
 ImmList(...$rounds); } #4Avoidmutablestate
  48. 48. function rounds(ImmList $players, $rounds = [])
 { $rounds[] = round($players); return count($rounds) < $players->length - 1 ? rounds(shift($players), $rounds) :
 ImmList(...$rounds); }
  49. 49. function schedule(ImmList $players)
 { return concat(rounds($players),
 inverse(rounds($players)); }
  50. 50. #2Eagerlyreplaceprimitiveswithtypes @_md#EagerDesign
  51. 51. “Mymathbackgroundmademerealise thateachobjectcouldhaveseveral algebrasassociatedwithit,andthere couldbefamiliesofthese,andthatthese wouldbeveryveryuseful...
  52. 52. ...Imadeupaterm"genericity"for
 dealingwithgenericbehavioursina
 quasi-algebraicform...
  53. 53. ...Ididn'tlikethewaySimulaIorSimula 67didinheritance.SoIdecidedtoleave outinheritanceasabuilt-infeatureuntilI understooditbetter.” AlanKay
  54. 54. http://bit.ly/meaning-­‐of-­‐oo
  55. 55. type Player = string; type Players = ImmList<Player>;
 type Match = Pair<Player,Player>
 type Round = ImmList<Match>;
 type Rounds = ImmList<Round>;
 type Schedule = Rounds;
 

  56. 56. function shift(Players $players): Players { return concat(head($players), last($players), init(tail($players)) ); }
  57. 57. function round(Players $players): Round
 { $sides = $players->splitAt($players->length/2); return $sides->_1->zip($sides->_2->reverse()); }
  58. 58. function rounds(Players $players, $rounds = [])
 : Rounds { $rounds[] = round($players); return count($rounds) < $players->length - 1 ? rounds(shift($players), $rounds) :
 ImmList(...$rounds); }
  59. 59. function schedule(Players $players): Rounds
 { return concat(rounds($players),
 inverse(rounds($players)); }
  60. 60. Composethedomainalgebra inside-out @_md#EagerDesign
  61. 61. namespace MdChessScheduleGeneration; shift(Players $players): Players
 round(Players $players): Round rounds(Players $players): Rounds schedule(Players $players): Schedule
  62. 62. ♞ Players => Schedule
  63. 63. Players => Rounds => Schedule ♞
  64. 64. Players => Round => Rounds => Schedule ♞
  65. 65. domainrulesaredefined againsttypes @_md#EagerDesign
  66. 66. { domainrules playerswillplaywitheveryotherplayer playerscan'tplaytwiceinthesameround everyplayermustplayineveryround playersmustplaytwicewithanotherplayer @_md
  67. 67. richdomainmodelvs
 leandomainmodel
  68. 68. S S S S S S @_md#EagerDesign richdomain
  69. 69. ImmutableState ImmutableState ImmutableState B B leandomain Laws
  70. 70. InterpretingServicesAgency Example @_md#EagerDesign
  71. 71. def request
 def decline
 def amend
 def accept
 def done

  72. 72. def request(details:JobDetails): Job
 def decline(ref:JobRef): Job
 def amend(details:JobDetails): Job => Option[TimeSheet]
 def accept(ref:JobRef): Job => Option[TimeSheet]
 def done(ref:JobRef): TimeSheet => Remittance
  73. 73. trait JobService {
 def request(details:JobDetails): Job
 def decline(ref:JobRef): Job
 def amend(details:JobDetails):Job => Option[TimeSheet] def accept(ref:JobRef): Job => Option[TimeSheet]
 def done(ref:JobRef): TimeSheet => Remittance }
  74. 74. trait JobService {
 def request(details:JobDetails): Job
 def decline(ref:JobRef): Job
 def amend(details:JobDetails):Job => Option[TimeSheet] def accept(ref:JobRef): Job => Option[TimeSheet]
 def done(ref:JobRef): TimeSheet => Remittance }
  75. 75. f(a:A):M[B]
 
 g(a:B):M[C]
  76. 76. f(a:A):M[B]
 f(a) map g = M[M[C]] 
 g(a:B):M[C]
  77. 77. f(a:A):M[B]
 join f(a) map g = M[C] 
 g(a:B):M[C]
  78. 78. f(a:A):M[B]
 andThen 
 g(a:B):M[C]
  79. 79. request andThen amend andThen done
  80. 80. def execute(input:Input): Unit path = input("path").getOrElse("specs") loadSpecs(path) andThen runSpecs andThen presentResults
  81. 81. what’stheeagerpoint? @_md#EagerDesign
  82. 82. merging2cells!! @_md#EagerDesign
  83. 83. { 3cases samevalue differentvalue righthandsideis empty
  84. 84. if ($this->value == $another->value) { return Pair(Cell(), Cell($this->value + $another->value)); } elseif ($another->isEmpty()) { return Pair(Cell(), Cell($this->value)); } return Pair(Cell($this->value), Cell($another->value));
  85. 85. if ($this->value == $another->value) { return Pair(Cell(), Cell($this->value + $another->value)); } elseif ($another->isEmpty()) { return Pair(Cell(), Cell($this->value)); } return Pair(Cell($this->value), Cell($another->value));
  86. 86. if ($this->value == $another->value) { return Pair(Cell(), Cell($this->value + $another->value)); } elseif ($another->isEmpty()) { return Pair(Cell(), Cell($this->value)); } return Pair(Cell($this->value), Cell($another->value));
  87. 87. function swipe($lines) {
 return $lines->map(function ($line) { 
 $lineCopy = mergeLine($line);
 while (!isLineMerged($lineCopy)) {
 $lineCopy = mergeLine($lineCopy); }
 return $lineCopy;
 });
 }
  88. 88. EagerDesign ♞ Jumptotheproblemworthsolving Eagerlyreplaceprimitiveswithtypes Compose[thedomainalgebra] inside-out Avoidmutablestate #1 #2 #3 #4 @_md#EagerDesign
  89. 89. marcelloduarte @_md #EagerDesign
  90. 90. Thankyou! ♞ @_md bit.ly/inviqa-contact bit.ly/inviqa-careers #EagerDesign
  • cyriux

    Nov. 8, 2017
  • wasselovski

    Sep. 15, 2016
  • powerirs

    Jun. 30, 2016
  • alexeyshockov

    Jun. 26, 2016

What happens when the very frameworks, tools and patterns we cherish take the reins and forces us to focus on all the boilerplate scaffolding things, distracting us from really solving the real problems? Sometimes the outside-in approach can lead us to code that is more complex and coupled than it has to be. Eager Design offers a fresh approach. Instead of being led by the delivery mechanisms, frameworks and patterns, we focus on the problems worth solving. Inspired by functional programming and Domain Driven Design, the principles of Eager Design helps us isolate and solve complex problems in a more focused and decouple manner.

Views

Total views

1,526

On Slideshare

0

From embeds

0

Number of embeds

22

Actions

Downloads

8

Shares

0

Comments

0

Likes

4

×