Why Mixins? - A Comparative Description
- Brent Lewis
- Mar 23, 2023
- 2 min read
Some programming languages have a feature called Mixins. Google's Dart is such a language. I had read about them long ago, but I'm now encountering them for the first time in practice while working with some Dart code. I wanted to more deeply understand what they were and how they were useful. I searched online tutorials, and while they would, of course, explain how to write them, nothing I read explained why I would want to use them over some other design pattern. Being a professional developer, I hoped that some resources would leverage the software engineer's vocabulary to make comparative explanations. Alas, I didn't find any. Now that I believe I've come to understand them (at least in Dart), I'll attempt to share what I've learned by way of comparison. Another title for this could be "Dart Mixins for the C# developer." (Note: C# has also added mixins in recent versions)
Mixins are like C# abstract classes in that they allow us to define an interface for implementers and write reusable concrete methods that work atop that interface. Mixins are different from abstract classes because mixins have no polymorphism. When a derived class is compiled in C#, it contains a virtual table and an indirection to a value of the derived class can be converted into an indirection to a value of the abstract class. A mixin instead makes a copy of every method and field in the implementer, as if the user copy-pasted it before compiling. There's no substitution of "this" back to the original reusable methods. This is helpful for languages that don't have proper multiple-inheritance, common for garbage-collected languages like Dart and C#. You can't polymorphically inherit multiple abstract classes, but you can inheret several mixins. For Dart at least, mixins can also specify an existing interface they work with, similar to extension methods on interfaces in C#. The concrete methods of the mixin are made aware of the members of the interface, and can access them. Mixins are different from extension methods on interfaces, because while an extension method on an interface affects all classes that implement that interface, a mixin still has to be inherited by a class in order to take effect. Mixins are different from extension methods and abstract classes in that mixins can access the private and protected members of the implementer.
Wow, that was really dense! I suppose that was the point. Mixins, like abstract classes and extension methods, are about code reuse. Developing an intuition of where and how to effectively use mixins will require learning to think completely differently about is-a relationships and the encapsulation of private and protected members.
Commentaires