Interfaces
----------

In general things have a "shape" - a way that they behave when they are used.
In many cases there are more than one thing which have this shape and function,
for example a cup will generally have the same shape and function as another.
As such, they can in general be treated interchangably, though you may have a
favourite cup, which all other things being equal you would prefer to use.

The idea here - already a fundamental part of xia2 but which can be built on -
is to more precisely define interfaces and functions, so that they may be
truly interchanged. In many cases a component will express more than one
interface, for instance my_favourite_mug is a cup and also is a paperweight.
In some cases there may also be dependencies between interfaces. A more useful
example here is that an implementation of an interface for indexing diffraction
images should also express an interface for handling diffraction images, as
will an implmentation of an interface for integrating such images.

Implementations
---------------

Implementations of these interfaces must do so by inheriting from the
interface class and implementing the protected methods. In cases where there
are dependencies the order of inheritance will be important. Essentially the
idea is that the interface will present a standard API on the outside which is
the fulfilled however inside - if this involves coordinate transformations then
so be it.

One interesting side-effect is that by inheriting from an interface it is
possible to register that an implementation is available without having to
have any code inside the implementation.

Implementation Registry
-----------------------

If we have more than one implementation and they all do essentially the
same thing, it should be possible to ask the registry for an implementation
and just use it. However, in the favourite cup example above, we also need to
be able to specify which implmentation.
