Mixins are bad?

Interesting post by Michele Simionato:

The idea of creating classes by composing reusable collections of methods is quite old: for instance Flavors, and old Lisp dialect, featured mixins more that 25 years ago. Nevertheless, there are still people thinking that the idea is new and cool: as a consequence, we see a lot of new code where the idea is misused or abused. Writing a paper showing the downfalls of mixins is in my opinion worth the effort.

Injecting methods into a class namespace is a bad idea for a very simple reason: every time you use a mixin, you are actually polluting your class namespace and loosing track of the origin of your methods. In this sense, using a mixin in a class is just as bad as using from module import * in a module. However, everybody agrees that it is much better to use the full form mymodule.myname instead of importing all the names in the global namespace, but nobody realizes that importing methods into a class via a mixin is potentially just as bad.

For instance, have a look at the hierarchy of the Plone Site class which I report in appendix. Between square backets you can see the number of methods/attributes defined per class, except special attributes. The plot comes from a real Plone application I have in production. The total count is of 38 classes, 88 names overridden, 42 special names and 648 regular names: a monster.To trace the origin of the methods and to keep in mind the hierarchy is practically impossibile. Moreover, both autocompletion and the builtin help facility become unusable, the self-generated class documentation become unreadable since too big.

In other words, a design based on mixins works for small frameworks, but it does not scale at all to large frameworks. Actually, Zope 3 has been entirely rewritten with the goal of avoiding the mixin abuse of Zope 2 and to use composition instead of inheritance (this is basically what the buzzwords Component Architecture really mean).

A consequence of namespace pollution is that it is very easy to have name clashes. Since there are hundreds of methods and it is impossible to know all of them, and since method overriding is silent, this is a real problem: the very first time I subclassed a Plone class I run into this issue: I overrode a pre-defined method inadvertently, by causing hard to investigate problems in an unrelated part of the code.

Her argument against mixins sounds like the arguments against big inheritance trees, and she reminds me why composition is better than inheritance. Mixins, in her telling, are even worse than inheritance because the inheritance is less explicit and comes from so many directions.

Of course, composition can lead to tight coupling, which makes code old and brittle and resistant to change. Composition can be done in a loose way if you use a lot of wrapper classes, insulating the calling class from the class that is called. Lots of wrapper classes can have the problem that they slow the code down, and make it more complex. I went down that road, once, years ago, and then eventually I got angry at my own code, for being too complex.

I eventually came up with a simple manager of dependency (a single object that manages dependency throughout the code).  One of my goals has been to keep my code as easy-to-read as possible for any future programmer who might have to replace me. I worry about the complexity that comes from inversion of control and dependency injection, but that is one viable way of maintaining loose coupling as my code evolves over time. Introducing a dependency manager is one of the few design decisions I’ve made that possibly makes it harder for new programmers to understand my code, but I believe the benefits out weigh the risks.

One Response to “Mixins are bad?”

  1. Closer To The Ideal » Blog Archive » Method name collisions become a big problem when you rely too much on modules Says:

    [...] He seems worried that someone is going to criticize him because of his criticism of modules. Yet his criticism is almost the same as Michele Simionato wrote in last month’s explicitly anti-module post. [...]

Leave a Reply