introducing eager design
TRANSCRIPT
laws of subtraction
what isn’t there can often trump what is. the simplest rules create the most effective experience. limiting information engages imagination. creativity thrives under intelligent constraints. break is the important part of breakthrough. doing something isn’t always better than doing nothing.
Matthew E. May
Eager Design
how♞
Jump to the problem worth solving Eagerly replace primitives with types Compose [the domain algebra] inside-out Avoid mutable state
#1 #2 #3 #4
@_md#EagerDesign
outside-in
unit test code
refactor
acceptance
ui/controller/views
orm, libs, domain objects
framework stuff (forms…)
model/view/controller
events
outside-inUI
Domain
core
Application
Infrastructure
mobile UI
port/adapter
port/adapterDB
http
s://p
bs.tw
img.
com
/med
ia/C
HyU
AukW
gAA5
iYS.
jpg
reads
writes
the right outside
http://bit.ly/modellingbyexample
http://bit.ly/whencucumbersgobad
@_md#EagerDesign
Eager Designwh
endone trivial
donenot trivial
not done
no idea[based on Cynefin, Snowden 03]
@_md#EagerDesign
Eager Designwh
endone trivial
donenot trivial
not done
no idea[based on Cynefin, Snowden 03]
Outside-in
@_md#EagerDesign
Eager Designwh
endone trivial
donenot trivial
not done
no idea[based on Cynefin, Snowden 03]
Eager Design
Outside-in
@_md#EagerDesign
Eager Designwh
endone trivial
donenot trivial
not done
no idea[based on Cynefin, Snowden 03]
Eager Design
Outside-in
¯\_(ツ)_/¯
@_md#EagerDesign
{ chess appwe add players it generates the schedule we can enter the results we can see the ranking
TRIVIA
L
TRIVIA
L
TRIVIA
L
Eager Design
@_md
{ domain rulesplayers will play with every other player
players can't play twice in the same round
every player must play in every round
players must play twice with another player
@_md
laws of subtraction
what isn’t there can often trump what is. the simplest rules create the most effective experience. limiting information engages imagination. creativity thrives under intelligent constraints. break is the important part of breakthrough. doing something isn’t always better than doing nothing.
Matthew E. May
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->reverse());}
function rounds(ImmList $players, $rounds = []) { $rounds[] = round($players);
return count($rounds) < $players->length - 1 ? rounds(shift($players), $rounds) : ImmList(...$rounds);}
function rounds(ImmList $players, $rounds = []){ $rounds[] = round($players);
return count($rounds) < $players->length - 1 ? rounds(shift($players), $rounds) : ImmList(...$rounds);}
function rounds(ImmList $players, $rounds = []){ $rounds[] = round($players);
return count($rounds) < $players->length - 1 ? rounds(shift($players), $rounds) : ImmList(...$rounds);}
function rounds(ImmList $players, $rounds = []){ $rounds[] = round($players);
return count($rounds) < $players->length - 1 ? rounds(shift($players), $rounds) : ImmList(...$rounds);}
#3 Compose
function rounds(ImmList $players, $rounds = []){ $rounds[] = round($players);
return count($rounds) < $players->length - 1 ? rounds(shift($players), $rounds) : ImmList(...$rounds);}
#4 Avoid mutable state
function rounds(ImmList $players, $rounds = []) { $rounds[] = round($players);
return count($rounds) < $players->length - 1 ? rounds(shift($players), $rounds) : ImmList(...$rounds);}
“My math background made me realise that each object could have several
algebras associated with it, and there could be families of these, and that these
would be very very useful...
...I didn't like the way Simula I or Simula 67 did inheritance. So I decided to leave
out inheritance as a built-in feature until I understood it better.”
Alan Kay
type Player = string;type Players = ImmList<Player>; type Match = Pair<Player,Player> type Round = ImmList<Match>; type Rounds = ImmList<Round>; type Schedule = Rounds;
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->_2->reverse());}
function rounds(Players $players, $rounds = []) : Rounds{ $rounds[] = round($players);
return count($rounds) < $players->length - 1 ? rounds(shift($players), $rounds) : ImmList(...$rounds);}
function schedule(Players $players): Rounds { return concat(rounds($players), inverse(rounds($players));}
namespace Md\Chess\ScheduleGeneration;
shift(Players $players): Players round(Players $players): Roundrounds(Players $players): Roundsschedule(Players $players): Schedule
{ domain rulesplayers will play with every other player
players can't play twice in the same round
every player must play in every round
players must play twice with another player
@_md
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
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
}
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
}
def execute(input:Input): Unit path = input("path").getOrElse("specs")
loadSpecs(path) andThen runSpecs andThen presentResults
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));
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));
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));
function swipe($lines){ return $lines->map(function ($line) { $lineCopy = mergeLine($line);
while (!isLineMerged($lineCopy)) { $lineCopy = mergeLine($lineCopy); }
return $lineCopy; }); }
Eager Design
♞
Jump to the problem worth solving Eagerly replace primitives with types Compose [the domain algebra] inside-out Avoid mutable state
#1 #2 #3 #4
@_md#EagerDesign