Friday, October 27, 2006

Mutually Exclusive Interfaces

Jason Nussbaum has posed a nice juicy thought experiment - how do you handle mutually exclusive interfaces? I started typing a comment, but it got too long, so here's my take on it :

The question was:

Had a thought: how do people handle mutually exclusive interfaces?

I suppose there's no such thing as mutually exclusive interfaces from a code perspective, but from a logic perspective, there may be. For example, let's say you do one of two things based on whether a class implements one of two interfaces. What do you do if something implements both?

It's a conceptual problem - as Jason says, there's not really a technical way that interfaces could be mutually exclusive. You can think of it this way - if an object X implements interface Y, then what you're really saying is "X can act like a Y". So there's no reason why X can't also act like a Z, depending on the situation.

There are so many ways you could tackle this problem. You could introduce a super-interface:

public interface DeadOrAlive{ public boolean isAlive(); }

public interface Dead extends DeadOrAlive{
public void startToSmell();
public interface Alive extends DeadOrAlive{
public void breathe();

...and thus force implementers of Dead or Alive to provide a method which indicates if they are alive or not. This feels like a bit of a kludge, but to my mind, less so than without.

You could add Exceptions onto the signature methods of Dead and Alive, which might throw NotDeadException and NotAliveException respectively - but this actually feels more kludgey to me than the first case.

I think the "proper" way to think of this is maybe the biggest kludge of all - as your object model is meant to reflect the real-world problem that you're modelling, if it produces this kind of conflict then maybe you need to re-think your model!

- unless, of course, your name happens to be Schrödinger...

public interface Alive{ public void breathe(); }
public interface Dead{ public void startToSmell(); }

public class Cat implements Dead, Alive
public void startToSmell();
public void breathe();

public class Box
private Cat cat;

public void putCatInBox();

...eep, lame quantum physics jokes on a Friday?! I think it's time for coffee...

Wednesday, October 25, 2006

Enron Explorer Going Viral

Since we got Boing Boing'ed yesterday, Google Analytics shows that we've had over 21,000 page views so far - and that's just to the front page. Unfortunately the GA javascript can't be included in the main app, as it's pretty much all AJAX requests, so we'll have to wait for analysis of the Apache logs for full statistics.

I also put the Enron Explorer on 4 days ago - it's now been echoed by 112 people, including one who speaks Russian, by the looks of it. Google Analytics confirms that we've had visitors from 71 different countries, insterestingly enough including two from the Cayman Islands and one from an anonymising proxy - Kenny Boy, that's not you is it....?

Some of the comments are fantastic :

"Interesting (both technologically and economically) walk through the Enron e-mail archives"

"searchable database of all of enron's internal email from 99-02. WOW."

"A look into what the future could look like in corporate transparency and analysis."

"Enron emails. Gawd, did I just come?"

some of the tags that people have applied to it (under the posting history on the right) are also interesting - I always find it intriguing to see how other people see what we've done.

Tuesday, October 24, 2006

We got Boing Boing'ed!

Another way to hammer a webserver - the Enron Explorer got highlighted on Boing Boing, "The Most Popular Blog In The World" according to Technorati. And our traffic has gone through the roof, but the app is holding up thanks to judicious planning for heavy usage, and some hefty Squid proxying.

Remember kids, "Proper Planning Prevents Piss-Poor Performance"

....and Corny Cliches Create Copious Cringes...
and Aggravated Alliteration Attains Acute Annoyance.

Wednesday, October 18, 2006

The Enron Explorer!

Phew - at long last we've gone live, and I can finally blog about what we've been working on here!

( yeah, yeah, skip all that, what about Enron? )

Our next major product is aimed squarely at the enterprise market, and it's a tool to analyse and extract meaning from corporate data stores and email traffic. Based on this information extraction, we can then map social networks and analyse information flow throughout the organisation, and use this information to give a shot in the arm to communications effectiveness - forwarding emails to you that are especially relevant to you but that you might otherwise have missed, and letting you set "volume level" for each of your interests.

There's no end of applications for this kind of tech - everything from expertise analysis to Sarbannes-Oxley compliance. The hardest question of all, though, was what to call it. After a tortuous voting and lobbying process second only to the IOC in labyrinthine complexity, we finally settled on the name SONAR, as it kind of implies what the product does (scans things and identifies things that you need to know about) and it's also a merely-mildly-icky acronym - SOcial Networks And Relevance.

Anyway, while we were working on the early stages of SONAR, we needed a large set of plausible test data to test the NLP algorithms - sadly, my usual plethora of furry animals and pitiful puns just wasn't enough in this case - and Jan came up with a stroke of genius - the Enron email archive.

In Oct. 2003, the FERC released ~200,000 Enron emails into the public domain, as part of the inquiry into the Enron fraud. So we grabbed the database, imported it into a very early version of SONAR, and set it chugging away. The results were so absorbing that we can't stop fiddling with it! We decided it was a great way to demo our system, even though it's a very early version, so laydeeeez an' gennulmen, (drum roll) allow me to present....


Just click on a name or a theme to get in, and off you go. There's some real gems in the archive, ranging from the hilariously obscene :

Jeff Skilling to Andy Zipper:
Fuck you, you piece of shit. I can't wait to see you go down with the ship like all the other vermin. Smug, paranoid, unhappy mother fucker. Eat shit. which I think Andy Zipper responded with admirable restraint!

- to the heartbreaking:

Sato (Enron Japan) to Andy Fastow:
Please don't fire Enron Japan staff, we do nothing wrong! Please!!! [....] We know how serious is the situation but please don't fire us now. Our families are waiting for a happy chrismas and new year!!

We can (and often do) lose ourselves in this for ages - have an explore and enjoy finding out what they were saying to each other as the house of cards crumbled down around them.

On a technical note, the interface is written in RubyOnRails, with a Java backend. It's AJAX'ed up to the eyeballs - hey, we even have rounded corners and gradient fills on the AJAX loading indicators! - and although there are still a couple of issues to sort out, we've worked hard on maintaining the usual expectations of browser behaviour.

The back button works (with a couple of minor niggles), and you can bookmark and email the url of your current view, and it should (nearly!) always bring you back to the same point. There's some smooth integration between the Java applet visualiser and the AJAX calls too, although again there's still a couple of niggles to deal with.

There's a whole load of other niftiness going on behind the scenes, but I'll blog about that later. In the meantime, have fun with it, and if you find anything particularly juicy, leave a comment (either here or on the app itself) and share it with the world!

Wednesday, October 11, 2006

Styled Checkboxes and Radio Buttons

I'm sure you've experienced the problem - most form elements can be styled pretty easily, but checkboxes and radio buttons? Forget it. If you're anything like me, you probably gave up by now and accepted that it's just one of those things you have to put up with. However, Philip Howard has released a nice CSS and JS solution that allows you to wrap a span of a certain class around the elements you want styled, and the magic pixies will do the rest.

I've seen this done before, but this solution is worth highlighting because :

  • It degrades gracefully back to the standard form elements if your browser does not support JS, CSS or images, and
  • He's put the extra bit of effort in to support the standard keyboard controls for form elements - space bar toggles status, left and right move the focus along a group of radio buttons, etc.

Nice one Philip.

Wednesday, October 04, 2006

Breaking Dependencies With Interfaces

I just picked up on Mike Dinowitz's post Interfaces - Why Bother? asking for benefits that interfaces offer. I started typing a comment, but realised that my two-penn'orth was way too sprawling for a comment and needed a whole post of its own. So here goes - I'm sure this won't be telling someone as experienced as Mike anything he doesn't know, but there's also been a call for more introductory-level blog posts in the last couple of days, so hopefully someone out there will find this useful as a concrete example of where I'd be lost without interfaces.

I'm currently working on a large J2EE platform with over 2000 classes. The only sensible way to manage such complexity is to split it into several distinct modules, each of which is conceptually self-contained and compiled and unit-tested separately, in a strict order. The ANT build script builds the core framework module first, then the email server, then the groups and user modules, etc etc, finally finishing up with the Tapestry-based web interface.

This all works great, except that you're still left with cross-module dependencies. The email server needs to know that group emails should be forwarded to group members, the groups module needs to know about its users, and so on.

The way these dependencies are resolved, is through interfaces. In the email module, we create an interface that represents the bit of group- or member- related functionality that the email server needs to know about - in this case, the ability to accept and propagate an email - and make the group and member objects (which come after the email server) implement that interface.

So we make an interface called EmailPropagator with one method - propagate() - in the email server module, and make groups and members implement EmailPropagator.

This way, the email server doesn't need to know anything else about the "thing" it's sending email to - so long as it implements EmailPropagator, the email server can ask it to propagate email to whoever or wherever it feels like, and that's all that the email server needs to know about it in order to do its job.

We can make anything be accepted by the email server, so long as it implements that one method. It could be a group / mailing list, an individual person, a spam demon that forwards ten thousand copies to random addresses, a black hole that just swallows it up, a file store.... anything, so long as it implements that one method.

This is part of the power of OO, and particularly the power of interfaces. It's also different from inheritance - in Java, and hence CF too, a class can only extend one base class. However, it can implement as many different interfaces as you like. You've heard of "If it looks like a duck and quacks like a duck, it must be a duck...." - well, this extends to "If it quacks like a duck, I don't care what it is, so long as I can ask it to quack".

It's one of the guiding mantras of OO that you should "design to interfaces, not implementations" and this is exactly why - we can make a million different things plug into our email server and do a million different actions with an email, without ever needing to change the email server code. That's power, and that's reusability. And that's why I love interfaces.

How Enterprise 2.0 Products Can Succeed

Much food for thought on Andrew McAfee's blog discussing John Gourville's concept of the "9x Email" problem which new technologies must overcome - "a mismatch of 9 to 1 between what innovators think consumers want and what consumers actually want."

People - real people, not tech people, who sometimes seem to be rabidly adopting the newest, most obscure technology for no other reason than to claim "geekier than thou" bragging rights amongst their peers - have an inbuilt tendency to stick with what they know. Gourville suggests that in order for new technology to go viral, it must offer a tenfold improvement over what's already out there. The problem is that in order to overcome the inertia associated with the status quo, en evolutionary, not revolutionary approach is called for:

Gourville's research suggests that the average person will underweight the prospective benefits of a replacement technology for it by about a factor of three, and overweight by the same factor everything they're being asked to give up

McAfee takes the example of email versus "groupware", and cites the intuitive nature of email interfaces as a point of comparison for Enterprise 2.0 apps. Just about everyone "gets" email as a concept, and the critical problem for Enterprise 2.0 technologies is one of interfaces. Rather than adding more and more bells and whistles to an interface, we should concentrate on making the interfaces clean, elegant, and instantly-comprehensible. This is a viewpoint I wholeheartedly share, but McAfee puts it very succinctly:

A great UI not only heightens the perceived benefits of a proposed collaboration technology, it also lowers the perceived costs.
The greatest challenge here, I think, doesn't have to do with making the browser sufficiently application-like ... It has to do with making technologists sufficiently user-like -- getting them to stop thinking in terms of bells and whistles and elaborate functionality, and to start thinking instead about busy users with short attention spans who need to get something done, and who can always reach for email

Insightful stuff.