dojo / compose

**DEPRECATED** Dojo 2 - composition library.

Home Page:http://dojo.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Allow deep mixin of prototype

kitsonk opened this issue · comments

Enhancement

Related to comments in dojo/widgets#29, it might make sense to have a feature that allows one level deep mixin of properties. While I am not sure of how this fits the sort of idiomatic patterns that exist, but I can see a utility there.

The current challenge is that if we want to modify the behaviour of methods, the only easy pattern we have is to aspect the method and apply some form of advice to it. In a true mixin situation, it becomes difficult to keep track of what advice is being applied and often requires external knowledge of the mixin, causing fairly hard dependencies. For example the use case of collecting attributes for a virtual node when rendering a widget. We currently have getNodeAttributes(). Currently there are two choices to modify this behaviour:

  1. Overwrite and re-implement the functionality - This is a sort of sledge hammer, obscuring any other sort functionality that may or may not be implemented in another mixin and you can't be certain other mixins won't do the same thing.
  2. Aspect with before/after/around - This means you have to assume that the method is there and while it sort of decouples other dependencies, and advice can easily be layered without explicit knowledge of the other advice, it can be surprising in how the advice is actually applied.

An alternative could be a reduction of methods though, where any mixin could add additional methods to an array and the core mixin that provides the getNodeAttributes() method, would reduce those methods to the final set of node attributes. But in order to support this, we would need compose to provide a mechanism for expressing those methods to be concatenated for each mixin, resulting in a prototype that contains the final array to be reduced.

My current thinking is that during the compose process, anything that is an Array in the destination prototype and the prototype to be mixed in, would perform a dest.array.concat(source.array) and then during instantiation and construction of the prototype, instance.array = proto.array.slice(0) before running the initialize functions.

Clearly, this idea is open for debate and certainly "complicates" compose by adding some features, but we are encountering challenges elsewhere, which I still don't think are best served by something like C3MRO or super() and classical inheritance. This might be a pattern established somewhere else, or we might be inventing something "new", but I would rather find a practical solution, irrespective of it being an established pattern.