Skip to content

Instantly share code, notes, and snippets.

@mrunderhill89
Created March 10, 2015 00:50
Show Gist options
  • Save mrunderhill89/b98b01aeaf8bcd0c0d23 to your computer and use it in GitHub Desktop.
Save mrunderhill89/b98b01aeaf8bcd0c0d23 to your computer and use it in GitHub Desktop.
An implementation of mixin to go along with my Interface class.
define(['underscore', 'interface'], function(_, Interface){
mixin_interface = new Interface({
proto_methods:["mix"],
static_methods:["proto_mix"]
});
var Mixin = mixin_interface.implement({
fields:{
default_mixins:[],
default_property:"mixin"
},
methods: {
//Mixes the given functions from this mixin into another object directly.
mix: function(target, functions){
functions || (functions=this.default_mixins);
var is_array = _.isArray(functions);
_.defaults(target,
_.reduce(functions, function(methods, object_f, mixin_f){
if (is_array){mixin_f = object_f};
methods[object_f] = function(){
return this[mixin_f].apply(this,arguments);
}.bind(this);
return methods;
}.bind(this),{})
);
return this;
}
},
static: {
//Mixes the given functions into an object prototype.
//The "property" field locates a mixin instance within the target object.
proto_mix:function(prototype, property, functions){
property || (property = this.default_property);
functions || (functions=this.default_mixins);
var is_array = _.isArray(functions);
return _.defaults(prototype,
_.reduce(functions, function(methods, object_f, mixin_f){
if (is_array){mixin_f = object_f};
methods[object_f] = function(){
var instance = this[property];
return instance[mixin_f].apply(instance,arguments);
};
return methods;
},{})
);
},
/*
Implements a new class that inherits from Mixin.
Yeah, I know the whole point of using Mixins is to move away from
implementation inheritance, but this is the fastest way to make new
mixins, so I'll concede on this point. All the parameters from Instance.implement
are supported, as well as the following new ones:
-default_mixins: sets up default mixin functions.
-default_property: sets up default property for prototype mixing.
-interface: lets you select an interface for the finished object.
The interface is automatically appended onto Mixin.interface.
*/
implement: function(params){
params = params || {};
return mixin_interface.implement(
_.extend(params,{
methods: _.extend(params.methods, {mix: this.prototype.mix}),
static: _.extend(params.static, {proto_mix: this.proto_mix})
})
).implements(params.interface);
},
}
});
return Mixin;
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment