avatarEric Elliott

Summarize

We don’t need a standard for single inheritance. Single inheritance taxonomies are an anti-pattern.

It could be composition all the way down, using a variety of very simple techniques in factory functions.

With `Object.assign()`:

import singleAncestor from './singleAncestor';
import customStuff from './customStuff';
const myNewThing = Object.assign({}, singleAncestor, customStuff);

Of course that doesn’t give you all the neat stuff like encapsulation, custom `propertyDescriptors`, the ability to deep merge certain properties, and so on. You can do all of those things inside a factory.

That’s why we made the Stamp Specification for composable factory functions.

With the Stamp Specification, it looks like this:

import singleAncestor from './singleAncestor';
import customStuff from './customStuff';
const specializedThing = compose(singleAncestor, customStuff);
const instance = specializedThing();

And it’s trivial to extend that to:

const specializedThing = compose(singleAncestor, customStuff, even, more, amazing, goodness);

Using class, you always have to choose some base class that decorators are extending (this is being generous… ES6 doesn’t support decorators).

Using composition, you don’t have to lock yourself into design decisions like that which may be wrong for new use cases.

Using class, you’re forced to use `new`, which could break calling code if you need to refactor to a different instantiation method later.

Using composition, a factory is just a normal function. Whatever instantiation method you chose inside the function has no impact on the caller.

To maximize project velocity, you need to maximize your freedom to extend and adapt your software in the future.

You say you’re making a pragmatic choice with `class`, but `class` makes it much harder to adapt your design for new use cases.

Is `class` pragmatic in the short term? Maybe, but in the long term, not at all.

JavaScript
Programming
Recommended from ReadMedium