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