I. Mixin Pattern and Code Reuse
The most commonly used code reuse method is inheritance, subclasses get all properties of parent class, so may inherit redundant properties. One solution is to split parent class properties into multiple interface classes, subclasses can "self-select" properties needed to inherit from these interface classes, but interfaces in Java are completely abstract (don't contain implementation), cannot achieve code reuse. Using composition can alleviate this problem, but cannot fundamentally solve it, composition needs to hold references to each dependent object, on this basis re-encapsulate and provide interfaces, increasing complexity
If only want to reuse some properties of existing objects, Mixin pattern is undoubtedly the best choice, because completely no need to involve complex class hierarchy relationships. On existing inheritance mechanism, we hope to achieve partial inheritance (only get needed part of properties from parent class) and multiple inheritance (can get properties from multiple parent classes), Mixin pattern does this thing
II. Implementation of Mixin Pattern
Implementation of Mixin pattern is actually a kind of property copying, example code as follows:
// Parts warehouse 1
function Moveable() {}
Moveable.prototype.walk = function() {
console.log('walked slowly');
}
Moveable.prototype.run = function() {
console.log('ran quickly');
}
Moveable.prototype.jump = function() {
// ...
}
// Parts warehouse 2
function Souled() {}
Souled.prototype.smile = function(age) {
console.log('smiled as ' + age + ' year\'s old kid');
}
// Parts warehouse 3
// mixin
function augment(sub, sup) {
// Inherit all properties
if (arguments.length === 2) {
for(var attr in sup.prototype) {
sub.prototype[attr] = sup.prototype[attr];
}
}
// Inherit partial properties
else if(arguments.length > 2) {
for (var i = 2; i < arguments.length; i++) {
sub.prototype[arguments[i]] = sup.prototype[arguments[i]];
}
}
else {
// do nothing
}
}
// Class needing enhancement
function Robot(name) {
this.name = name;
}
// Enhance
augment(Robot, Moveable, 'walk', 'run'); // Inherit walk and run from Moveable
augment(Robot, Souled); // Inherit all properties of Souled
// test
var robot = new Robot('little boy');
robot.walk(); // walked slowly
robot.run(); // ran quickly
robot.smile(12); // smiled as 12 year's old kid
Easily achieved partial inheritance and multiple inheritance, released from constraints of classic inheritance mechanism, making code reuse more flexible
Some JS libraries provide Mixin implementation, for example Underscore's _.extend method, JQuery's extend method, YUI's mix/augment/extend/merge methods etc.
III. Disadvantages of Mixin Pattern
Mixin is a very flexible code reuse method, but injecting functionality into prototype objects leads to prototype pollution and uncertainty in function source, may be a serious problem in large systems. Can solve function source uncertainty problem through detailed documentation, but prototype pollution is unavoidable
References
-
"JavaScript Design Patterns"
No comments yet. Be the first to share your thoughts.