Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

When should you prefer inheritance patterns over mixins in dynamic languages?

By mixins, I mean actual proper mixing in, as in inserting functions and data members into an object in runtime.

When would you use, for example, prototypal inheritance instead of mixins? To illustrate more clearly what I mean by mixin, some pseudocode:

asCircle(obj) {
  obj.radius = 0
  obj.area = function() {
    return this.radius * this.radius * 3.14
  }

myObject = {}
asCircle(myObject)
myObject.area() // -> 0
share|improve this question
2  
Mixins are more like cross-cutting aspects than straight-up inheritence. That will probably define some use-cases for you. –  ashes999 Dec 5 '11 at 13:52
1  
Composition, anyone :) –  OnesimusUnbound Dec 6 '11 at 8:52
add comment

4 Answers

up vote 9 down vote accepted

Prototypical inheritance is simple. It has a single advantage over mixins.

That is that it's a live link. if you change the prototype everything that inherits it is changed.

Example using pd

var Circle = {
  constructor: function _constructor() {
    this.radius = 0;
    return this;
  },
  area: function _area() {
    return this.radius * this.radius * Circle.PI
  },
  PI: 3.14
};

var mixedIn = pd.extend({}, Circle).constructor();
var inherited = pd.make(Circle, {}).constructor();

Circle.perimeter = perimeter;

inherited.perimeter(); // wins
mixedIn.perimeter(); // fails

function perimeter() {
  return 2 * this.radius;
}

So basically, if you want changes to the "interface" Circle to reflect at run-time to all objects that "use" it's functionality, then inherit from it.

If you do not want changes to reflect then mix it in.

Note that mixins have more purpose than that as well. Mixins are your mechanism for multiple "inheritance".

If you want an object to implement multiple "interfaces" then you will have to mix some in. The one you use for prototypical inheritance is the one you want changes to reflect for at run-time, the others will be mixed in.

share|improve this answer
add comment

Well, the best example I can give it to you is an Actor for a game which has inheritance for some base stuff but uses mixins/plugins for shared functionality. The shared functionality could be (directly from the source code!):

var plugins = {
    SingleVisualEntity : SingleVisualEntity,
    JumpBehaviour      : JumpBehaviour,
    WeaponBehaviour    : WeaponBehaviour,
    RadarBehaviour     : RadarBehaviour,
    EnergyGatherer     : EnergyGatherer,
    LifeBarPlugin      : LifeBarPlugin,
    SelectionPlugin    : SelectionPlugin,
    UpgradePlugin      : UpgradePlugin,
    BrainPlugin        : BrainPlugin,
    PlanetObjectPlugin : PlanetObjectPlugin,
}
share|improve this answer
add comment

My horse sense tells me this:

  • If something is useful across multiple objects or class hierarchies -- make it a mixin
  • If something is only useful along a single hierarchy -- use inheritance

Related Notes:

  • The word "useful" should be taken metaphorically
  • For those languages that don't have multiple inheritance, mixins are a good alternative
  • PHP 5.4 introduces traits that have goodness from both mixins and multiple inheritance worlds
share|improve this answer
    
+1 , my favorite example of "something useful across multiple objects or class hierarchies" in Ruby is Enumerable module : ruby-doc.org/core-1.9.3/Enumerable.html –  David Dec 5 '11 at 14:31
    
I would say that multiple inheritance can be a (not so good) alternative to mixins. –  Simon Dec 6 '11 at 10:43
    
@Simon I would say that mixins can be a (not so good) alternative to multiple inheritance ;) –  Raynos Dec 6 '11 at 14:02
add comment

Use the "Is-a" test.

Inheritance is limited to the case when you can say "Subclass IS A Superclass". They are the same kind of thing. "Cheese is a Dairy Product".

Mixins are for everything else. "Cheese can be used in a sandwich". Cheese isn't a sandwich, but it participates in sandwiching.

PS. This has nothing to do with dynamic languages. Any multiple inheritance language with static compilation (i.e., C++) has the same decision point.

share|improve this answer
    
Definitely +1- static languages have mixins too. –  DeadMG Dec 6 '11 at 8:08
    
Right, mixins can be done in many languages - this was not my question. Dynamic languages have certain properties which might or might not make mixins different and/or more interesting in such languages - Raynos pointed one aspect out. Furthermore, you don't point out any specific reasons why one should use the IS A concept over the mixin concept. –  Magnus Wolffelt Dec 6 '11 at 9:30
    
@MagnusWolffelt: They are the same kind of thing. "Cheese is a Dairy Product". That's the rule for IS-A. What more should I say? –  S.Lott Dec 6 '11 at 10:51
    
My question is more about design decisions - in what situations do you want inheritance, and for what reasons? In dynamic languages I see few reasons for picking inheritance over mixins, besides what Raynos described. Performance of object creation might be one reason. –  Magnus Wolffelt Dec 6 '11 at 12:15
    
@MagnusWolffelt: "in what situations do you want inheritance" When the two classes satisfy the IS-A relationship. "Performance of object creation" is not a reason for choosing one over the other. Inheritance makes a very strong statement about the two classes of objects. Mixins makes a weaker and more flexible statement. Inheritance is used when the two classes satisfy the "IS-A" relationship. What more could I say? I can't understand your question very well. Can you clarify what more you'd like to know? –  S.Lott Dec 6 '11 at 12:28
show 11 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.