Strict MVC Checks in Java

Lately, I’ve been digging into my finances (kids, they’re as expensive as they are adorable). My budget was somehow borked, but a surface experiment with it delivered no joy.  I realised I had to go deeper.

To figure out why the budget said I was in the red, but the bank balance continued getting happily more black, I decided that I would redo the budget utility. The budget initially started out as an Excel spreadsheet, then got beefed up with some Excel/VBA, which at some stage I moved across to OpenOffice and its not quite-the-same macro language.    The decision to go with Java was nothing more that wanting to brush up on my rusty Java skills.

The utility goes under the working title “PersonalFinancier”, and can be found on GitHub. Here’s a picture of it currently doing its magic:

A screenshot of the PersonalFinancier

A screenshot of the PersonalFinancier

Now, there’s an amount of MVC going on in the utility itself. There’s a budget model, a bunch of controllers, and a small number of view components. The most important view components are the tables that watch most of the model state one way or another.

I decided at some stage that with the MVC, I wanted to be absolutely certain at runtime that I had my views and controllers explicitly state that they were views and controllers.  I also wanted the system to check that this was the case.

The solution I settled on involved a design-by-contract approach implementing the following:

  • Separate interface definitions for the view and control classes of any given model.
  • The model checking at subscription time that the subscriber implemented the relevant view interface
  • The model checking whenever state was being updated that the state-altering class implemented the controller interface
  • The checking mechanisms implemented as asserts, allowing me to switch the checking off on a release build, but have them actively enforcing their interface contracts in a development/test build.

Below, the solution in gory detail:

MVC View and Controller Contracts

I introduce two interface definitions per model. One for the model viewers, and one for model controllers. The wiew interface extends Java’s Observer interface, as I’m happy to use the Publish-Subscribe pattern support that comes straight out of the box.

/* public interfaces for controller and view components to implement for a model */
public interface StrictModelViewer extends Observer {};
public interface StrictModelComtroller;

Runtime Model Checking with Asserts

My model class extends the Observable class. The example code below shows a method that changes model state that should only be invoked by a controller, and the “addObserver()” method of Observer overrriden to check that the new observer implements the correct view interface.

Given that these check functions seem rather generally reusable, the assert calls delegate the checks to a class library of generic reflection utilities.

The state-changing controller check is handled by the call to ReflectionUtilities.callerImplements().

Checking that the observer implements the correct view interface is handled by the call ReflectionUtilities.classImplements().

public class StrictModel extends Observable {

  public void alterModelState() {
    assert ReflectionUtilities.callerImplements(
      StrictModelController.class
    );

    this.setChagned();
    this.notifyObservers();
  }

   public void addObserver(Observer observer) {
     assert (
        ReflectionUtilities.classImplements(
            observer.getClass(),
            StrictModelViewer.class
        )
     ) : "observer specified does not implement the interface StrictModelViewer";

     super.addObserver(observer);
  }
}

We typically can’t determine the caller of a method without reflection. The trick in Java seems to be to create a new Throwable instance,
and walk its stack trace back up to the call wer’re interested in.

Here, it’s not the callerImplements() call we want to know the calling method of, but the caller of it’s caller (two up the stack). Once we have the method, we check to see whether it’s defining class matches the interface we’re interested in. It
does this rather neatly via the classImplements() method.

  /**
   * Checks to see if the method calling whatever method that
   * invokes <tt>callerImplements</tt> implements the
   * supplied interface.
   * @param theInterface
   * @return
   */
  public static boolean callerImplements(Class<?> theInterface) {

    StackTraceElement[] elements = new Throwable().getStackTrace();

    String callerClassName = elements[2].getClassName();
    Class<?> callerClass = null;
    try {
      callerClass = Class.forName(callerClassName);
    } catch (Exception e) {
       return false;
    }
    return classImplements(callerClass, theInterface);
  }

The classImplements() method interrogates via reflection, which interfaces a class implements and checks to see if one of those interfaces matches
the one we want. A naive approach of simply checking which interfaces a class implements, however, fails when it is the super-class of the one  specified that implements our desired interface. The reflection call getInterfaces() will only return the interfaces of a class, not including any super-class interfaces.

A thorough solution needs to check all interfaces implemented on the current class and all its super-classes. The getInterfacesForClass() method call below uses a touch of recursion to walk a class tree to the lowest base class, collecting all interfaces found as it goes.

  /**
   * Checks to see if the supplied class implements the supplied interface.
   * @param theClass
   * @param theInterface
   * @return
   */
    /**
   * Checks to see if the supplied class implements the supplied interface.
   * @param theClass
   * @param theInterface
   * @return
   */
  public static boolean classImplements(Class<?> theClass, Class<?> theInterface) {
    ArrayList<Class<?>> interfaceArray = getInterfacesForClass(theClass);
    if (interfaceArray.contains(theInterface)) {
      return true;
    }
    return false;
  }

  /**
   * Recursively build and returns a list of all interfaces implemented by the
   * supplied class and all its superclasses.
   * @param theClass
   * @return
   */
  private static ArrayList<Class<?>> getInterfacesForClass(Class<?> theClass) {

    if (theClass == null) {
      return null;
    }

    Class<?>[] interfaceArray = theClass.getInterfaces();
    Class<?> theSuperclass = theClass.getSuperclass();

    ArrayList<Class<?>> totalInterfaces = new ArrayList<Class<?>>();
    for (Class<?> currInterface : interfaceArray) {
      totalInterfaces.add(currInterface);
      totalInterfaces.addAll(getInterfacesForClass(currInterface));
    }
    ArrayList<Class<?>> superClassInterfaces = getInterfacesForClass(theSuperclass);
    if (superClassInterfaces != null) {
      totalInterfaces.addAll(superClassInterfaces);
    }

    return totalInterfaces;
  }

Deactivating Checking on a Release Build

The above is a rather heavy-handed approach to ensuring that only viewers view a model, and only controllers control it. Once I’m convinced that I’ve wired it all up correctly, I’d like to not carry these extra CPU-cycles at runtime. That’s why I’m using Java’s assert functionality here and have rigged Eclipse to run debugging with asserts turned on.  Note that a small amount of tinkering is needed in Eclipse to get asserts working.

And that’s how I’ve implemented actually checking that my model’s viewers and controllers are actually viewers and controllers for the given model.

Happy hacking!

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s