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?