designing js apis
DESCRIPTION
The Good, The Bad, and the UglyTRANSCRIPT
DESIGNING JS APIs
THE GOOD, THE BAD AND THE UGLY
GLOBO.COM
GLOBO.COM
BOOKING.COM
LOOP INFINITO
COLETANEA FRONT-END
DESIGNWHY
DEFINITION purpose, planning, or
intention that exists or is thought to exist behind
an action, fact, or material object
DESIGNWHY
APIs ARE DEVELOPERS
UX
DESIGNWHY
CODE IS WRITTEN
ONCE, READ MANY TIMES
DESIGNWHY
NOBODY READS
API DOCs
DESIGNWHY
BADTHE
GOODTHE
UGLYTHE
BADTHE
BADTHE
IMMUTABLE vs MUTABLE
var foo = [3, 5, 8]; var bar = foo.slice(1, 2);
console.log(foo); //=> [3, 5, 8] console.log(bar); //=> [5]
http://ariya.ofilabs.com/2014/02/javascript-array-slice-vs-splice.html
BADTHE
IMMUTABLE vs MUTABLE
var foo = [3, 5, 8]; var bar = foo.splice(1, 2);
console.log(foo); //=> [3] console.log(bar); //=> [5, 8]
http://ariya.ofilabs.com/2014/02/javascript-array-slice-vs-splice.html
BADTHE
IMMUTABLE vs MUTABLE
var foo = [3, 5, 8]; var bar = foo.sliced(1, 2);
console.log(foo); //=> [3, 5, 8] console.log(bar); //=> [5]
http://ariya.ofilabs.com/2014/02/javascript-array-slice-vs-splice.html
BADTHE
IMMUTABLE vs MUTABLE
var foo = [3, 5, 8]; foo.slice(1, 2);
console.log(foo); //=> [3]
http://ariya.ofilabs.com/2014/02/javascript-array-slice-vs-splice.html
BADTHE
DOUBLE NEGATIVE
foo.disabled = false;
bar.setHidden(false);
kung.invisible = false;
BADTHE
DOUBLE NEGATIVE
foo.enabled = false;
bar.setVisible(false);
kung.visible = false;
BADTHE
BOOLEAN TRAP
var opacitySlider = new Slider(true);
var volumeSlider = new Slider(false);
http://ariya.ofilabs.com/2011/08/hall-of-api-shame-boolean-trap.html
BADTHE
BOOLEAN TRAP
var opacitySlider = new Slider({ horizontal: true });
var opacitySlider = new Slider({ horizontal: false });
http://ariya.ofilabs.com/2011/08/hall-of-api-shame-boolean-trap.html
BADTHE
BOOLEAN TRAP
var opacitySlider = new SliderHorizontal();
var opacitySlider = new SliderVertical();
http://ariya.ofilabs.com/2011/08/hall-of-api-shame-boolean-trap.html
BADTHE
INCONSISTENCE
// inconsistence button.caption = “Lorem”;
radioButton1.value = “Easy”; radioButton2.value = “Medium”; radioButton3.value = “Hard”;
checkbox1.option = “Ipsum”; checkbox2.option = “Dolor”;
BADTHE
GOODTHE
UGLYTHE
GOODTHE
GOODTHE
STATIC POLYMORPHISM
POLYMORPSHISM IS WHEN MULTIPLE IMPLEMENTATIONS CAN RESPOND TO THE SAME
MESSAGE WITHOUT THE SENDER NEEDING TO KNOW ABOUT THE
IMPLEMENTATION
GOODTHE
STATIC POLYMORPHISM
// inconsistence button.caption = “Lorem”;
radioButton1.value = “Easy”; radioButton2.value = “Medium”; radioButton3.value = “Hard”;
checkbox1.option = “Ipsum”; checkbox2.option = “Dolor”;
GOODTHE
STATIC POLYMORPHISM
// static polymorphism // similar classes, same API button.value = “Lorem”;
radioButton1.value = “Easy”; radioButton2.value = “Medium”; radioButton3.value = “Hard”;
checkbox1.value = “Ipsum”; checkbox2.value = “Dolor”;
GOODTHE
NAMING BOOLEAN PROPs
// getters of boolean props should // start with *has*, *can* or *is* if (foo.isChecked()) { // ... }
GOODTHE
NAMING BOOLEAN PROPs
// getters of boolean props should // start with *has*, *can* or *is* if (foo.hasChildren()) { // ... }
GOODTHE
NAMING BOOLEAN PROPs
// getters of boolean props should // start with *has*, *can* or *is* if (foo.canBeClosed()) { // ... }
GOODTHE
SPECIALIZED METHODS
var car = new Vehicle(110, 2014, true, false);
var plane = new Vehicle(900, 2003, true, true);
GOODTHE
SPECIALIZED METHODS
var car = new Car(110, 2014);
var plane = new Vehicle(900, 2003);
GOODTHE
var car = new Car({ speedMax: 110, fabricationYear: 2014 });
var plane = new Plane({ speedMax: 900, fabricationYear: 2003 });
SPECIALIZED METHODS
VERBAL ACTIONS
status.message(“Lorem Ipsum”);
page.forward(); page.backward();
GOODTHE
VERBAL ACTIONS
status.showMessage(“Lorem Ipsum”);
page.goForward(); page.goBackward();
GOODTHE
BADTHE
GOODTHE
UGLYTHE
UGLYTHE
UGLYTHE
var letters = [“a”, “b”, “c”];
$.each(letters, function(index, val) {});
$.map(letters, function(val, index) {});
$(“li”).map(function(index, val) {});
Secrets of Awesome JS API Design — https://www.youtube.com/watch?v=QlQm786MClE
INCONSISTENCE
UGLYTHE
jQuery(selector [, context]) // Select
jQuery(element) // Wrap
jQuery(object) // Wrap
jQuery() // Empty $ object
jQuery(elementArray) // Wrap
jQuery(jQuery object) // Clone
jQuery(html [, ownerDocument]) // Create element
jQuery(html, props) // Create element
jQuery(callback) // Bind DOM loaded function
Secrets of Awesome JS API Design — https://www.youtube.com/watch?v=QlQm786MClE
NOT SPECIALIZED
UGLYTHE
var evento = “Front in Fortaleza”;
evento.substring(6, 8); // => "In" evento.substring(8, 6); // => "In"
http://ariya.ofilabs.com/2014/02/javascript-string-substring-substr-slice.html
INCONSISTENCE
UGLYTHE
http://ariya.ofilabs.com/2014/02/javascript-string-substring-substr-slice.html
var evento = “Front in Fortaleza”;
evento.substr(6, 8); // => "in Forta" evento.substr(8, 6); // => " Forta"
INCONSISTENCE
var evento = “Front in Fortaleza”;
evento.slice(6, 8); // => "in" evento.slice(8, 6); // => ""
http://ariya.ofilabs.com/2014/02/javascript-string-substring-substr-slice.html
UGLYTHE
INCONSISTENCE
UGLYTHE
http://bugs.jquery.com/ticket/13103
JQUERY BOOLEAN TRAP
$("#hoverme-stop-2").mouseenter(function() { $(this) .find("img") .stop(true, true) .fadeOut(); });
UGLYTHE
http://bugs.jquery.com/ticket/13103
JQUERY BOOLEAN TRAP
$("#hoverme-stop-2").mouseenter(function() { $(this) .find("img") .stop({ clearQueue: true, jumpToEnd: true }) .fadeOut(); });
UGLYTHE
http://bugs.jquery.com/ticket/13103
CASE CONSISTENCY
var myRequest = new XMLHttpRequest();
UGLYTHE
BOOLEAN TRAP
event.initKeyEvent( "keypress", true, true, null, null, false, false, false, false, 9, 0 );
SEE YOU COWBOY