Guido von Rossum is considering adding interfaces to Python.  In this article, he explains that the power of interfaces has forced a few major Python projects to implement their own version of interfaces, which is probably a sign that such a feature is needed in Python itself.

Mix-ins are strikingly absent from Guido’s discussion and I really wonder why.  Mix-ins don’t exactly address the same need as interfaces but they are a better fit for scripting languages where concrete and granular software contracts are more important then schemas.

I actually happen to think that mix-ins would be a very welcome addition to Java as well and I can think of many times when I have needed the functionality provided by a set of methods and I was forced to use one of the following three workarounds:

  • Move these methods in a separate class and make them static.
  • Extend the class they belong to (an approach that is wrong on many counts).
  • Use delegation.

Here is a concrete example of this problem.

Imagine that some of your classes need to expose the properties "shortName" and "longName" with getters and setters.  While interfaces let you specify this contract easily (an interface with four methods), you still need to find a way to capture this implementation in a separate class.

Let’s start with the obvious:

public class Nameable {
  private String m_shortName;
  private String m_longName;

  public String getShortName() {
    return m_shortName;
  }

  public void setShortName(String s) {
    m_shortName = s;
  }

  public String getLongName() {
    return m_longName;
  }

  public void setLongName(String s) {
    m_longName = s;
  }
}

At this point, Java forces you to use one of the three techniques described above, but imagine we could do the following:

public class Employee {
  import com.beust.Nameable;  // illegal Java
  // ...
}

Importing the class inside your own class is equivalent to doing a copy/paste of the content of the imported class, so that the following becomes valid:

Employee e = new Employee();
e.setShortName("Cedric");
e.setLongName("Cedric Beust");

There are a lot of things to like about this approach:

  • Your Employee class is much less verbose.  Getters and setters are notoriously verbose in Java and while the Ruby equivalent of Nameable would fit on one line, reading through the Java code adds a lot of noise around what should be a simple concept.
     
  • You are not perverting your type system by extending a class you have no clear "is-a" relationship with.
     
  • Changes to the imported class are automatically imported into your class, so you don’t need to keep up with them (as you would with delegation since need to implement new forwarding methods if new methods are added to the delegate).

One might argue that the methods imported are not obvious in your class, but this is no different from regular inheritance, and IDE’s can show the imported methods just as easily.

Once the concept of mix-ins is made available to you, you start looking at your code in very different ways and just when you thought you had done a pretty good job at creating small modular classes that interact nicely with each other and isolate the responsibilities in clear ways, you start realizing that you could decompose your architecture much further.  Interfaces allowed you to create a nice abstract schema of your code and mix-ins give you the power to create a nice concrete decomposition as well.  It’s code reuse at its best.

If you take this concept far enough, you end up with "Quantum Software Design", software that is made of a lot of very tiny pieces that you can mix and match at your leisure without compromising your architecture.

I already used the term "Quantum AOP" a couple of years ago to describe software made of tiny aspects that get woven together to create the final product.  This is a very similar concept except that instead of using AOP as the glue, we use a simple, albeit hypothetical as of today, feature of the Java language:  internal class imports.

Interestingly, Quantum Software Design is also a technique that I started identifying recently in my Java code, but this time tied to a totally different framework.  I’ll keep the name of this framework secret for now so I can dedicate an entire entry to it very soon.