I've written some code which features Eric Elliot's javascript factory function mixin composition (https://medium.com/javascript-scene/javascript-factory-functions-with-es6-4d224591a8b1), but since there's no object field name associated with the class it doesn't seem like most other forms of composition I see. What would the draw backs be compared the style of composition where each class you compose with is given a field name (I'm calling this named composition)?
let pipe = (...fns) =>x => fns.reduce((acc,fn)=> {
return fn(acc)
},x)
let createCanvas= ()=>o=> ({
...o,
makeCanvas(width,height) {
this.can = document.createElement("canvas")
this.can.width = width
this.can.height = height
this.ctx = this.can.getContext("2d")
},
clearCanvas() {
this.ctx.clearRect(0,0,this.can.width,this.can.height)
},
returnCanvas() {
return this.can
}
})
let drawingLines = () => o => ({
...o,
line(x, y, xx, yy) {
this.ctx.beginPath();
this.ctx.moveTo(x, y);
this.ctx.lineTo(xx, yy);
this.ctx.stroke();
}
});
let mouseTracker = () => o => ({
...o,
trackCanvas() {
this.track(this.can);
},
track(ele) {
ele.addEventListener("mousemove", e => {
this.bb = ele.getBoundingClientRect();
this.mx = e.clientX - this.bb.left;
this.my = e.clientY - this.bb.top;
});
}
});
let rectMethods = () => ({
makeRect(x, y, w, h) {
this.ctx.strokeRect(x, y, w, h);
},
});
let rectMixin = () => o => ({
...o,
...rectMethods()
});
// apparently width gets set automatically, which is pretty nice
let height = 150;
let width= 150;
let firstCanvas = pipe(
createCanvas(),
drawingLines(),
mouseTracker(),
rectMixin()
)({});
firstCanvas.makeCanvas(width, height);
firstCanvas.trackCanvas();
I'm very interested in avoiding the verbosity of named composition, especially in cases where an existing class has many methods that I would have to rewrite the methods for.
let usefulEventFunctions=()=>({
//...imagine functions named one-five for countings sake...
evOne() {
},
evTwo() {
},
})
let usefulMathFunctions =()=>({
//...imagine another set of named functions one-five also...
mthOne(){
},
mthTwo(){
}
})
// here's the class composed of the others
let myObject = ()=>({
math:usefulMathFunctions(),
events:usefulEventFunctions(),
// below would be the 10 signatures
evOne() {
this.events.evOne()
},...
mthTen() {
this.math.mthTen()
}
})
Using the mixin composition I can see how we would avoid this in a language like javascript, but looking over https://stackoverflow.com/questions/49002/prefer-composition-over-inheritance, and Object Composition, it appears other languages only feature named composition, so how is one supposed to avoid all the duplicated methods in choosing composition over inheritance?