The document discusses the concept of composition in programming. It provides examples of how to compose objects and functions to maximize code reuse. It promotes writing small, single-purpose functions that can be reused and combined through patterns like chaining and piping. This allows building complex programs from simple, composable parts that work together through universal interfaces like streams.
6. How do I compose things?
Find repeated patterns or duplications in your
code and refactor them into reusable parts.
7. A simple example
var obj1 = {
message: 'hello world!',
sayHi: function () {
alert(this.message);
}
};
var obj2 = {
message: 'hey!',
sayHi: function () {
alert(this.message);
}
};
obj1.sayHi(); // 'hello world!'
obj2.sayHi(); // 'hey!'
8. A simple example
var obj1 = { message: 'hello world!' };
var obj2 = { message: 'hey!' };
var alerter = {
sayHi: function () {
alert(this.message);
}
};
obj1 = _.extend(obj1, alerter);
obj2 = _.extend(obj2, alerter);
obj1.sayHi(); // 'hello world!'
obj2.sayHi(); // 'hey!'
9. ● Maximize code reuse
● Use objects without classes
● Avoid traps of single-parent inheritance
Mixins
10. Mixins in the wild
● Marionette Behaviors
● Bootstrap CSS classes
● Hapi plugins
11. Underscore.js
_.each(array, function) : Loop over each item in an array
_.map(array, function) : Reformat each item in an array
_.filter(array, function) : Make a new array containing only items that pass a test
_.reduce(array, function, start) : Calculate a single value from an array of items
13. myArray
.map(/* reformat items */)
.filter(/* pull out items you don't need */)
.reduce(/* crunch down to a single value */)
You can do this in plain JS too
14. mapped = map(..., my_array)
filtered = filter(..., mapped)
final_val = reduce(..., filtered)
And in Python
16. var myList = [
{ count: 17 },
{ count: 22 },
{ count: 3 },
{ count: 18 }
];
var sum = 0;
for (var i = 0; i < myList.length; i++) {
sum += myList[i].count;
}
Function reuse
17. Function reuse
function getCount (value) {
return value.count;
}
function noOdds (value) {
return value % 2 === 0;
}
function add (value1, value2) {
return value1 + value2;
}
18. Function reuse
var myList = [
{ count: 17 },
{ count: 22 },
{ count: 3 },
{ count: 18 }
];
var sum = _.chain(myList)
.map(getCount)
.filter(noOdds)
.reduce(add)
.value();
19. each / map / filter / reduce
function getForms (data) {
var forms = data.aggregate.all[window.location.protocol + '//' + window.location.host];
var formsOut = [];
var url = window.location.toString();
var formsToExclude = [];
for (var key in data.aggregate.exclude) {
if (new RegExp('^' + key + '$').test(url)) {
formsToExclude = formsToExclude.concat(data.aggregate.exclude[key]);
}
}
var filteredForms = [];
for (value in forms) {
if (formsToExclude.indexOf(value) === -1) {
filteredForms.push(value);
}
}
for (key in data.aggregate.include) {
if (new RegExp('^' + key + '$').test(url)) {
forms = forms.concat(data.aggregate.include[key]);
}
}
return formsOut;
}
20. each / map / filter / reduce
function getForms (data) {
var forms = data.aggregate.all[window.location.protocol + '//' + window.location.host];
var url = window.location.toString();
var formsToExclude = [];
_.each(data.aggregate.exclude, function (val, key) {
if (new RegExp('^' + key + '$').test(url)) {
formsToExclude = formsToExclude.concat(val);
}
});
forms = _.filter(forms, function (val) {
return formsToExclude.indexOf(val) === -1;
});
_.each(data.aggregate.include, function (val, key) {
if (new RegExp('^' + key + '$').test(url)) {
forms = forms.concat(val);
}
});
return forms || [];
}
21. each / map / filter / reduce
● Small, single-purpose functions
● Maintainable
● Reusable
● Easy to test
● Universally understandable
22. Web components
● HTML is perfectly composable:
<form>
<input type="text">
<button>click me</button>
</form>
● Custom elements = infinite composition possibilities!
24. "This is the Unix philosophy: Write programs
that do one thing and do it well. Write programs
to work together. Write programs to handle text
streams, because that is a universal interface."
- Doug McIlroy
The Unix Philosophy
25. A Node.js API to read in data, act on it in
chunks, then then write out to a new stream.
Node streams