Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
No content
Slide 2
Slide 2 text
the$art$of$the$javascript$metaobject$protocol Duck%Typing,%Compa1bility,%and The$Adaptor$Pa-ern
Slide 3
Slide 3 text
No content
Slide 4
Slide 4 text
Duck%typing%is%a%style%of%typing%in% which%an%object's%methods%and% proper:es%determine%the%valid% seman:cs,
Slide 5
Slide 5 text
...rather'than'its'inheritance'from'a' par0cular'class'or'implementa0on'of' an'explicit'interface.
Slide 6
Slide 6 text
No content
Slide 7
Slide 7 text
Tastes&Like&Fruit
Slide 8
Slide 8 text
No content
Slide 9
Slide 9 text
Also%Tastes%Like%Fruit
Slide 10
Slide 10 text
"Write'code'that'depends'upon' tastes1like(fruit)'rather'than' depending'upon'is1a(fruit)."
Slide 11
Slide 11 text
No content
Slide 12
Slide 12 text
duck%typing%is%a Compa&bility,Technique
Slide 13
Slide 13 text
No content
Slide 14
Slide 14 text
A"Problem:
Slide 15
Slide 15 text
No content
Slide 16
Slide 16 text
Conway's)Game)of)Life
Slide 17
Slide 17 text
"Conway's*Game*of*Life*is*a*two2 state*cellular*automata."
Slide 18
Slide 18 text
An#Implementa+on 1. Cells,
Slide 19
Slide 19 text
An#Implementa+on 1. Cells, 2. Universe,
Slide 20
Slide 20 text
An#Implementa+on 1. Cells, 2. Universe,.and 3. View.
Slide 21
Slide 21 text
Cell 1. Neighbours,
Slide 22
Slide 22 text
Cell 1. Neighbours,.and 2. State.
Slide 23
Slide 23 text
function StandardCell () { this._neighbours = []; this._alive = false; }
Slide 24
Slide 24 text
StandardCell.prototype.neighbours = function neighbours (neighbours) { return this._neighbours; }; StandardCell.prototype.setNeighbours = function setNeighbours (neighbours) { this._neighbours = neighbours.slice(0); return this; };
Slide 25
Slide 25 text
StandardCell.prototype.alive = function alive () { return this._alive; }; StandardCell.prototype.setAlive = function setAlive (alive) { this._alive = alive; return this; };
Slide 26
Slide 26 text
No content
Slide 27
Slide 27 text
moving'through Time
Slide 28
Slide 28 text
Cell 1. Neighbours, 2. State,2and 3. Transforma9on2of2State.
Slide 29
Slide 29 text
Universe 1. Neighbourhoods.(not.shown),
Slide 30
Slide 30 text
Universe 1. Neighbourhoods.(not.shown),.and 2. Transforma:on.of.States.
Slide 31
Slide 31 text
StandardCell.prototype.nextAlive = function nextAlive () { var alives = this._neighbours.filter(function (n) { return n.alive(); }).length; if (this.alive()) { return alives === 2 || alives == 3; } else { return alives == 3; } };
Slide 32
Slide 32 text
Universe.prototype.iterate = function iterate () { var aliveInNextGeneration = this.cells().map( function (c) { return [c, c.nextAlive()]; } ); aliveInNextGeneration.forEach(function (a) { var cell = a[0], next = a[1]; cell.setAlive(next); }); };
Slide 33
Slide 33 text
No content
Slide 34
Slide 34 text
drawing Life
Slide 35
Slide 35 text
View 1. Drawing*a*Cell:
Slide 36
Slide 36 text
View.prototype.drawCell = function drawCell (cell, x, y) { var xPlus = x + this.cellSize(), yPlus = y + this.cellSize() this._canvasContext.clearRect(x, y, xPlus, yPlus); this._canvasContext.fillStyle = this.cellColour(cell); this._canvasContext.fillRect(x, y, xPlus, yPlus); return self; };
Slide 37
Slide 37 text
View.prototype.cellColour = function cellColour (cell) { return cell.alive() ? WHITE : BLACK; };
Slide 38
Slide 38 text
No content
Slide 39
Slide 39 text
No content
Slide 40
Slide 40 text
Ch#ch#ch#changes!
Slide 41
Slide 41 text
No content
Slide 42
Slide 42 text
redesigning(for Colour
Slide 43
Slide 43 text
function ColourCell () { this._neighbours = []; this._age = 0; } ColourCell.prototype.neighbours = StandardCell.prototype.neighbours; ColourCell.prototype.setNeighbours = StandardCell.prototype.setNeighbours;
Slide 44
Slide 44 text
ColourCell.prototype.age = function age () { return this._age; }; ColourCell.prototype.setAge = function setAge (age) { this._age = age; return this; };
Slide 45
Slide 45 text
No content
Slide 46
Slide 46 text
moving'through',me in#Colour
Slide 47
Slide 47 text
ColourCell.prototype.nextAge = function next () { var alives = this._neighbours.filter(function (n) { return n.age() > 0; }).length; if (this.age() > 0) { return (alives === 2 || alives == 3) ? (this.age() + 1) : 0; } else { return (alives == 3) ? (this.age() + 1) : 0; } };
Slide 48
Slide 48 text
Universe.prototype.iterate = function iterate () { var ageInNextGeneration = this.cells().map( function (c) { return [c, c.nextAge()]; } ); ageInNextGeneration.forEach(function (a) { var cell = a[0], next = a[1]; cell.setAge(next); }); };
Slide 49
Slide 49 text
No content
Slide 50
Slide 50 text
drawing(life in#Colour
Slide 51
Slide 51 text
var COLOURS = [ BLACK, GREEN, BLUE, YELLOW, WHITE, RED ]; View.prototype.cellColour = function cellColour (cell) { return COLORS[ (cell.age() >= COLOURS.length) ? (COLOURS.length - 1) : cell.age() ]; }; // ...
Slide 52
Slide 52 text
No content
Slide 53
Slide 53 text
something Doesn't(Fit
Slide 54
Slide 54 text
Object.keys(StandardCell.prototype) // => [ 'neighbours', 'setNeighbours', 'alive', 'setAlive', 'nextAlive' ]
Slide 55
Slide 55 text
Object.keys(ColourCell.prototype) // => [ 'neighbours', 'setNeighbours', 'age', 'setAge', 'nextAge' ]
Slide 56
Slide 56 text
The$state$of$a$cell$is$now$"age"$ instead$of$"aliveness."
Slide 57
Slide 57 text
No content
Slide 58
Slide 58 text
These%changes%will Ripple&Through&Universe&and&View
Slide 59
Slide 59 text
our$problem$is$that Universe(is(coupled(to(Cell's( Interface
Slide 60
Slide 60 text
No content
Slide 61
Slide 61 text
No content
Slide 62
Slide 62 text
how$smart$people Solve&the&Problem
Slide 63
Slide 63 text
"Make&a&coloured&cell&behave&like&a& standard&cell."
Slide 64
Slide 64 text
ColourCell.prototype.alive = function alive () { return this._age > 0; };
Slide 65
Slide 65 text
ColourCell.prototype.setAlive = function setAlive (alive) { if (alive) { this.setAge(this.age() + 1); } else this.setAge(0); return this; };
Slide 66
Slide 66 text
ColourCell.prototype.nextAlive = StandardCell.prototype.nextAlive;
Slide 67
Slide 67 text
Object.keys(ColourCell.prototype) // => [ 'neighbours', 'setNeighbours', 'age', 'setAge', 'nextAge', 'alive', 'setAlive', 'nextAlive' ]
Slide 68
Slide 68 text
Presto!(Backwards(Compa2bility. (it$"tastes$like$a$standard$cell")
Slide 69
Slide 69 text
No content
Slide 70
Slide 70 text
universe(and(cell(are No#Longer#Coupled
Slide 71
Slide 71 text
No content
Slide 72
Slide 72 text
At#What#Cost?
Slide 73
Slide 73 text
No content
Slide 74
Slide 74 text
Increasing*Flexibility Increases(Complexity
Slide 75
Slide 75 text
No content
Slide 76
Slide 76 text
No content
Slide 77
Slide 77 text
there%is Another(Way
Slide 78
Slide 78 text
"Make&a&cell&that&behaves&like&a& Standard&Cell,&but&is&implemented&in& terms&of&a&Coloured&Cell."
Slide 79
Slide 79 text
function AsStandard (colouredCell) { this._colouredCell = colouredCell; } var tastesLikeAStandardCell = new AsStandard(aColourCell);
Slide 80
Slide 80 text
AsStandard.prototype.neighbours = function neighbours () { return this._colouredCell.neighbours(); }; AsStandard.prototype.setNeighbours = function setNeighbours (neighbours) { this._colouredCell.setNeighbours(neighbours); return this; };
Slide 81
Slide 81 text
AsStandard.prototype.alive = function alive () { return this._colouredCell.age() > 0; };
Slide 82
Slide 82 text
AsStandard.prototype.setAlive = function setAlive (alive) { if (alive) { this._colouredCell.setAge(this._colouredCell.age() + 1); } else this._colouredCell.setAge(0); return this; };
Slide 83
Slide 83 text
AsStandard.prototype.nextAlive = function nextAlive () { return this._colouredCell.nextAge() > 0; }
Slide 84
Slide 84 text
Object.keys(AsStandard.prototype) // => [ 'neighbours', 'setNeighbours', 'alive', 'setAlive', 'nextAlive' ]
Slide 85
Slide 85 text
When%we%Upgrade%to%ColourCell 1. View'can'depend'upon'ColourCell,
Slide 86
Slide 86 text
When%we%Upgrade%to%ColourCell 1. View'can'depend'upon'ColourCell,'and 2. Universe'can'depend'upon'AsStandard.
Slide 87
Slide 87 text
Sweet! 1. Universe*is*decoupled*from*changes*to*Cell,
Slide 88
Slide 88 text
Sweet! 1. Universe*is*decoupled*from*changes*to*Cell,*and 2. ColourCell*isn't*burdened*with*backwards*compa>bility.
Slide 89
Slide 89 text
No content
Slide 90
Slide 90 text
AsStandard)is)an)Adaptor
Slide 91
Slide 91 text
The$adapter$(sic)$pa/ern$is$a$ so2ware$design$pa/ern$that$allows$ the$interface$of$an$exis8ng$class$to$ be$used$from$another$interface...
Slide 92
Slide 92 text
It#is#o'en#used#to#make#exis0ng# classes#work#with#others#without# modifying#their#source#code.
Slide 93
Slide 93 text
TIMTOWTDI
Slide 94
Slide 94 text
No content
Slide 95
Slide 95 text
good$programmers$borrow$from$smalltalk, Great&Programmers&Steal&from&C++
Slide 96
Slide 96 text
function colourFromStandard (standard) { return new ColourCell() .setNeighbours(standard.neighbours()) .setAge(standard.alive() ? 1 : 0); }
Slide 97
Slide 97 text
function standardFromColour (colour) { return new StandardCell() .setNeighbours(colour.neighbours()) .setAlive(colour.age() > 0); }
Slide 98
Slide 98 text
No content
Slide 99
Slide 99 text
No content
Slide 100
Slide 100 text
Coproxies
Slide 101
Slide 101 text
No content
Slide 102
Slide 102 text
No content
Slide 103
Slide 103 text
Approaching+the+End
Slide 104
Slide 104 text
No content
Slide 105
Slide 105 text
adaptors Separate'Concerns
Slide 106
Slide 106 text
No content
Slide 107
Slide 107 text
and$thus,$adaptors Isolate(Change
Slide 108
Slide 108 text
No content
Slide 109
Slide 109 text
and$they Decouple(Modules
Slide 110
Slide 110 text
No content
Slide 111
Slide 111 text
adaptors Solve&Compa+bility&Problems
Slide 112
Slide 112 text
No content
Slide 113
Slide 113 text
but$they$also$gives$us$the$freedom$to Make%Changes,%Safely
Slide 114
Slide 114 text
No content
Slide 115
Slide 115 text
when%we're%using%teams%to%build%so3ware%at%scale Adaptors)are)an)Important)Tool
Slide 116
Slide 116 text
No content
Slide 117
Slide 117 text
No content
Slide 118
Slide 118 text
one$more$thing:
Slide 119
Slide 119 text
No content
Slide 120
Slide 120 text
No content
Slide 121
Slide 121 text
when%you're%holding%a Version(Shaped.Hammer
Slide 122
Slide 122 text
No content
Slide 123
Slide 123 text
all#changes#look#like Migra&on)Shaped/Nails
Slide 124
Slide 124 text
No content
Slide 125
Slide 125 text
Packages(Have(Interlocking( Dependencies
Slide 126
Slide 126 text
No content
Slide 127
Slide 127 text
Migra&ons*Can*Cascade you$never$know$how$much$work$a$single$upgrade$can$cause
Slide 128
Slide 128 text
No content
Slide 129
Slide 129 text
migra&on)is)expensive,)so)semver)values Backwards)Compa.bility
Slide 130
Slide 130 text
No content
Slide 131
Slide 131 text
"duck&typed"&backwards&compa2bility Holds&Progress&Back
Slide 132
Slide 132 text
No content
Slide 133
Slide 133 text
breaking)compa.bilty Exposes'Clients'to'Bugs
Slide 134
Slide 134 text
No content
Slide 135
Slide 135 text
adaptors(decouple Compa&bility,from,Progress
Slide 136
Slide 136 text
No content
Slide 137
Slide 137 text
adaptors(provide Safe%Compa*bility
Slide 138
Slide 138 text
No content
Slide 139
Slide 139 text
What%would%an%adaptor.aware% package%manager%look%like?
Slide 140
Slide 140 text
An#Adaptor*Aware#Package#Manager 1. Interfaces,and,Implementa1ons,would,be,independantly, versioned,
Slide 141
Slide 141 text
An#Adaptor*Aware#Package#Manager 1. Interfaces,and,Implementa1ons,would,be,independantly, versioned, 2. Interfaces,would,have,a,many
Slide 142
Slide 142 text
An#Adaptor*Aware#Package#Manager 1. Interfaces,and,Implementa1ons,would,be,independantly, versioned, 2. Interfaces,would,have,a,many
Slide 143
Slide 143 text
An#Adaptor*Aware#Package#Manager 1. Interfaces,and,Implementa1ons,would,be,independantly, versioned, 2. Interfaces,would,have,a,many
Slide 144
Slide 144 text
No content
Slide 145
Slide 145 text
an#adaptor)aware#package#manager#could Change'the'Way'We'Grow'So0ware
Slide 146
Slide 146 text
No content
Slide 147
Slide 147 text
and$that$provides Food$for$Thought for$a$very$long$,me$indeed
Slide 148
Slide 148 text
No content
Slide 149
Slide 149 text
Tack%Så%Mycket!
Slide 150
Slide 150 text
Reg$Braithwaite,$ GitHub,$Inc. raganwald.com,•,@raganwald Ar#pelag,*Stockholm,* September*19,*2014