23 Mixin Pros And Cons
Advantages
Mixin classes tend to be simple because they represent simple orthogonal concepts. The complexity of combining them is left to the compiler. It is left up to the compiler to generate fast, efficient, code, making heavy use of inlining.
OO programs often exploit dynamic polymorphism to achieve code reuse. For example the decorator design pattern is often used. A decorator object could apply a rotation of 90 degrees to the GUI control that it decorates. This approach is different to mixins in the following respects:
- A run time decorator class requires a member variable which is a pointer to the object being decorated. The programmer must write the code to initialise this member. E.g. it could be provided in a constructor or an initialisation method;
- Dynamic polymorphism is required so the same decorator can be applied to many different kinds of objects at run time;
- Compile time assembly instead becomes run time assembly. This can be inconvenient to express in procedural code. Code that creates and wires up objects at run time is typically more verbose than using mixin chains, where binding of method calls through the chain is implicit;
- Very fine grained run time assembly can lead to objects that seem mysterious - such as an object that rotates another object;
- Run time assembly can exacerbate the problem of supporting persistence (i.e. assuming the assemblies themselves are to be made persistent). There are great performance overheads for persisting fine grained graphs or trees of objects, and perhaps even more significantly it greatly complicates the problem of schema evolution;
- There is inevitably the overhead of indexing into a vtable for each method call, and more significantly it defeats the inlining capabilities of the compiler; and
- There are more objects to be heap allocated.
It is possible to get the best of both world using mixins on interface delegators.
Disadvantages
Mixins are a useful technique, but hardly a panacea. There are some significant disadvantages:
- Execution of statements at run time tends to jump around in different mixins, making it hard to follow and debug
- Potential for long compile times
- Potential for bloated binaries : mixins easily lead to code bloat if not used carefully. It can be a problem having large functions in mixins, because there is a tendency to duplicate the code for many different instantiations.
- Increased dependencies
- It is unclear how to invoke base class constructors, there is a tendency to use the two stage construction pattern