30 October 2008

When to use Interfaces

The simplest answer: never. Use Ruby or any other dynamic language instead! But if you're still stuck in javaland, well, I promised this article in Programming for the Stone Age after witnessing some serious interface-itis. My university Software Engineering courses all talked about "always code to an interface" and articles abound on this insidious meme. So you get interface-implementation couples, where every method signature on the class is duplicated on the interface, pointlessly. I remember with horror a proprietary ORM I was obliged to use that actually required this pairing for every persistent class. It was unfortunately the backbone of our application, and hurt more than raw SQL. But that was in the days before Hibernate and the whole POJO movement, so let's call it a learning experience. Let us end the tedium of obligatory signature copying for every little property we add to our applications!

Right. So you're building your application, you decide your domain objects will include Customer, Supplier, Product(*). You already have a concept: a Domain Object, a kind of a thing that is unlike a Controller, or Service, or a Repository. A Domain Object has nothing in common with a HashMap or String or JdbcConnection. Major distinguishing features of Domain Objects are that each instance can be uniquely identified from among all Domain Object instances; each Domain Object is subject to CRUD operations and may be in an unsaved or deleted state. You might have decided for your application that objects are never deleted from your database, but rather they are tagged as deleted. You might decide that all domain objects should have a human-readable name. If any of this is the case, it is possible, depending on the nature of your application, that an interface resembling the following may be useful:

DomainObject.java
interface DomainObject {
  UniqueIdentifier getUID(); // this isn't necessarily the database id of the object
  String getName();
  boolean isSaved();
  boolean isDeleted();
}

With this interface in place, you can write some methods whose behaviour will be consistent for all of your domain objects:


  public void update(DomainObject o) {
    if (o.isDeleted()) {
      throw new CantUpdate("object " + o.getUID() + " is already deleted");
    }

    ...
  }

  public String renderLink(DomainObject o) {
    return "<a href='/object/" + o.getUID() + "'>" + o.getName() + "</a>";
  }

Customer and Supplier have a feature in common: they are contactable. That is, they have addresses, phone numbers, emails and so on. It would be nice to handle contact information in a uniform way: to do so, the Contactable interface might be handy:

Contactable.java
interface Contactable {
  String getAddress();
  void setAddress(String address);
  String getEmail();
  void setEmail(String email);

  ... etc ...
}

Armed with Contactable, you can manage contact information in a uniform way:


  public void verify(Contactable c) {
    ...
  }

  public String renderContactInfo(Contactable c) {
    ...
  }

Last example: Auditable : for those Domain Objects for which all changes need to be audited. If your application requires all objects are audited, you might as well merge this with DomainObject (and you might make it a superclass rather than an interface).

Auditable.java
interface Auditable {
  User modifiedBy();
  Date modifiedOn();
  void updated(User by, Date when);
}

Auditable works well in combination with a Hibernate interceptor or event handler so that every object that is persisted and requires auditing, is guaranteed to be audited with no more effort than adding "implements Auditable" to your class definition. This way, together with the magic of hibernate, your business-logic code can deal with modifying your object in a clear and readable fashion, without a heap of audit-code clutter. For example:

MyHibernateInterceptor.java
class MyHibernateInterceptor {
  boolean onSaveDirty(Object o, Stuff... otherStuff) {
    if (o instanceof Auditable) {
      ((Auditable) o).updated(getUser(), new Date());
    }

    ... etc ...
  }

  ... etc ...
}

So you end up with domain classes looking a little like this:

Customer.java
class Customer implements DomainObject, Auditable, Contactable {

  ... interface methods ...

  ... other methods unique to customer ...
}

Java interfaces allow you slice up a big class into smaller, managable chunks so that you can write well-targeted pieces of code that guarantee consistent behaviour over a range of different objects.

Lastly and most importantly: don't create the interface until you really need it. If you have only one implementation, and there is only one possible implementation (at least for the moment), then you don't need an interface. The day you have a second implementation of the same concept, hit Refactor -> Extract Interface in Intellij (**) to introduce your interface quickly and painlessly. And I really mean painlessly. Intellij will hunt down all references to the old class in your code, and convert them where possible into references to the interface. And you get to decide whether the class keeps its name and the interface gets a new name, or the other way around.

There is a whole universe of refactorings out there: "extract interface" is so trivial and easy to understand that it can be automated. So use it. When you have the freedom to evolve your code in any direction at the last minute, you implicitly have the freedom to keep your codebase much simpler by not evolving it until the last minute.

Good luck, and let me know how it goes.

(*) It looks like e-commerce is the "hello world" of web-app bloggers (**) I'm sure Eclipse and Netbeans have this refactoring too.

25 October 2008

Tales of the Interview

Recruiting is not only for colleagues: we recruit everybody. It is the world's biggest problem: getting the right people into the right jobs, eliminating the waste and drag of unproductivity engendered by poorly matched people and positions. We recruit babysitters, bankers, plumbers, spouses, presidents, even if the recruitment process is completely different in each case. The only people we can't recruit are our blood relations.

This post was triggered by two recruitment-horror-story posts from the world's best blog: A Problem at the Personal Level, and The Receptionist Test. They're worth a read.

It scares me how some software organisations hire coders on the basis of nothing more than their CV, a handshake, and a smile. If you do nothing else in a programming interview, please do this: sit in front of a computer with your candidate, and ask her, or him, to write some code. This alone is the best filtering tool you have, it's so powerful you won't want to look at CVs ever again.

Tips for programming interviews:

  • Take time at the beginning of the interview to help your candidate relax so they can put on their best performance. If you've done this, and they're still nervous and stressed, you need to think about having a nervous and stressed person on your team. If you haven't done this, and they perform poorly due to stress, you might have missed your best candidate.
  • The more developers from the team are involved, the better (perhaps a rotating three-person interviewing team for example).
  • Over time, build up a collection of programming exercises. You will need a string of performances in order to be able to judge comparatively, but you will also need a variety of exercises so that you can choose, for a given candidate, the exercise that allows their strengths to shine.
  • Don't waste time on candidates that you haven't pre-screened with some basic technology questions first. (Really basic. Eg, What's the difference between a Set and a List?)
  • There are many kinds of programming exercise.
    • Pattern-oriented: because you (probably) need these in your project: you can find or design an exercise that requires Command, or Strategy or example
    • For someone claiming to be a java "expert", design an exercise that shows a mastery of exception handling and inner-class use.
    • Find (or write) some particularly nasty code that your candidate can refactor and write tests for.
    • Best of all: don't interrupt your work, turn your current project task into an exercise. No interview exercise can be more relevant than this!
    • Avoid algorithm-oriented problems, (sorting, searching, packing, etc) - because libraries exist for this kind of thing so these exercises don't test real-world experience so well.
    • Avoid framework-specific problems (eg Swing, Hibernate): an exercise requires too much setup and context, and ordinary spoken Q&A are best for evaluating technology-specific knowledge.
  • Incorporate test-automation. A solid candidate will grasp testing concepts even if they are not familiar with the frameworks you use.
  • It's not just about coding and technical skills. This is your chance to sit next to your candidates, to work with them, as if they were already on your team. Do they have a sense of humour? The right kind of humour for your team? Are they comfortable, relaxed, confident? Do they listen, take the time to understand you, and verify that they understood you, before launching into the problem? Do you really want to work with this person?
  • You're not a born interviewer. You will make mistakes. I did. Get over it. Interview more.

Gladwell argues in Blink that although we make snap judgements all the time, whether we can trust these judgements is a matter of experience. With a few years of interview practice, your snap judgements will gradually become more and more accurate. And maybe, at that point, a firm handshake and a quick, friendly, confident smile will be enough?

Now if there was a way to do this for presidents, and plumbers ... the world might be a different place ...

24 October 2008

CSS can replace many lines of Javascript

Here's a trick that has saved me dozens of lines of javascript. Say you need to toggle your page between two modes - for example beginner/expert, verbose/concise, update/read-only, screen/printer. You could set a cookie or request parameter and reload the page, but that may not be efficient, it calls for a lot of code server-side. More practically, you could write some javascript that iterates over your DOM, identifies target elements, and toggles some aspect of their state in conformity with the desired mode. But again, it's a lot of code, only this time on the client-side.

Or you could do the following. Use a CSS classname to identify elements that should be visible in one mode or the other. For example, ifVerbose and ifConcise.

any-page.html
  <body class='verboseMode'>
    <a href='/blah/blah' class='ifVerbose'>
      This is a link to /blah/blah where you 
      will discover a lot of blah.
    </a>
    <a href='/blah/blah' class='ifConcise'>/blah/blah</a>
  </body>

The CSS is trivial: any ifVerbose element on a conciseMode page is invisible, and vice-versa.

application.css
  .verboseMode .ifConcise {
    display: none;
  }

  .conciseMode .ifVerbose {
    display: none;
  }

All you need now is a tiny bit of javascript to toggle the classname of your root element between conciseMode and verboseMode.

application.js

  var verbose = function(v) {
    if (v) {
      $(document.body).addClassName('verboseMode');
      $(document.body).removeClassName('conciseMode');
    } else {
      $(document.body).addClassName('conciseMode');
      $(document.body).removeClassName('verboseMode');
    }
  }

Much less work than toggling with javascript in a big loop, no? Let the browser's CSS engine do the work!

21 October 2008

Sending binary data from Freemarker

There are probably many better alternatives to writing binary content with Freemarker: for example write your data to the filesystem and let apache serve it. But sometimes you have no choice and you need to serve your png or jpg or doc or pdf from a freemarker template.

The solution involves setting the content type, like when sending javascript from freemarker. Then we need an object having access to the data with a method to write it for us.

send-png-image.ftl
${res.setContentType("image/png")}${action.writeData(res.getOutputStream())}
The framework you are using should have injected the HttpResponse object into the Freemarker context. For example, Webwork/Struts2 creates a "res" variable which you can access from your Freemarker templates. The writeData implementation need not differ much from this:
SendImage.java
 ...

public void writeData(OutputStream os) throws IOException {
   os.write(this.getByteArray(this.image));
 }

...

It would be nice to simply write ${res.outputStream.write(byteArray)} in Freemarker, and dispense with the Java method - but Freemarker wraps the byte[] byteArray in a SequenceAdapter (ooh, a Design Pattern), and doesn't unwrap it again when we just want the byte array. So we need a writeData method or equivalent in java.

The same principle works for other kinds of binary content - photos, movies, documents, pdfs, etc - set the right content-type. If you want the browser to open a "Save As ..." dialog instead of displaying the content inline, add this after the content-type declaration:

${res.setHeader("Content-Disposition", "attachment; filename=${fileName}" )}

Special Note for writing Excel

Set your content-type as follows: ${res.setContentType("application/vnd.ms-excel; charset=UTF-8")}, and then write your data as a HTML table. That's all! Trivial! No POI, no hacks, no bridging to VB. The only thing you need worry about is escaping some of the data so Excel doesn't misinterpret it.

His Serene Highness

This is Ferdinand-Philippe, the Duke of Orléans, who died in a car accident in 1842. (*).

His statue reminds me of someone I worked with briefly a few years ago. Pompous, arrogant, disdainful, and overdressed. If you're a duke, and the king's son, you can probably get away with it.

If you're a low-ranking manager, try another strategy.

* It was actually a "voiture à cheval", a horse and carriage. Modern vehicles kill people much more effectively, but it is interesting that the culture of death on the roads was already in place so long ago.

16 October 2008

risible-db: database migrations in java

Jean-Philippe Hallot, and I, are pleased to offer the world risible-db, a new, free, really simple, 100% java open-source utility library for managing database schema migrations in a manner not wholly unlike rails migrations. The class of interest is (somewhat unimaginatively) called Migrations, with a convenience subclass called WebInfMigrations that does a lot of the convention-over-configuration thing for you. Use as follows:

in your Spring applicationContext.xml config
<bean id="migrations" class="risible.db.WebInfMigrations" init-method="start">
  <property name="dataSource" ref="myDataSource"/>
</bean>
You can of course auto-wire the datasource. There is no other property to set. When Spring calls the init-method, start(), risible-db will look in a directory called migrations directly under your application's WEB-INF directory, for *.sql files, order them lexicographically, and execute any that have not already been executed against the current datasource. Here's an example:
/WEB-INF/migrations
001-add-widgets-table.sql
002-add-users-table.sql
003-add-permissions.sql
003-add-widget-tags.sql
004-rename-widgets-to-woggles.sql
select * from migrations;
+---------------------------+
| name                      |
+---------------------------+
| 001-add-widgets-table.sql |
| 002-add-users-table.sql   |
| 003-add-widget-tags.sql   |
+---------------------------+
In this situation, risible-db migrations will execute 003-add-permissions.sql, and 004-rename-widgets-to-woggles.sql, because they are not already installed in the migrations table. Unlike Rails, risible-db considers the whole name of the migration, not just the number. So you can have multiple migrations with the same number; in fact risible doesn't care about the numbers at all, but it's a convenient way for you to keep your migrations in order. If you prefer A-add-widgets.sql, B-add-users.sql, etc, that's ok too. We found that the strict numbering approach called for a lot of number-management overhead when working in a distributed team - when the half of the team on this continent wanted to add a migration at the same time as the other half on another continent, we needed a way to ensure we wouldn't both use the same number, while simultaneously guaranteeing that the order of migrations respected schema dependencies. Each .sql file is a plain text file containing one or more sql commands, separated by semicolons. No comments, please. Notes:
  • Support for Oracle is coming in the next few days - right now it works only for MySQL
  • Respect and acknowledgements to Pascal Pratmarty who was the first to say, "well we could do that in java, too!"
  • future enhancements include down migrations like rails, conditional migrations (eg data migrations only to run in a test environment), other ways to express migrations (java code, for example), and SQL comments. Please comment if there's something on this list (or not) that you can't live without.
  • download here
  • Don't search for documentation. This is it.
  • It's LGPL licensed
Please let us know how it works for you, we'll be happy to hear your feedback.

08 October 2008

π is for porn

Today's favourite from reddit: π stands for porn ... and a host of other nasty things you never expected to see in maths classes ... watch out!

Parenting, Politics, and Manipulation

One of our first parenting books was a great little volumne called How to Con your Kid. It offers many toddler-survival tactics, my favourite being the offer-a-choice trick.

Yesterday, I was encouraging my daughter (age 2) to get into her stroller so we might go collect her brother at school.

ConanInto your stroller, sweetie-pie
DaughterI don't want to go into the stroller, I want to walk!
ConanShould I fasten the straps, or do you want to do it?
DaughterI want to do it.
ConanHmm. Well, just this once, ok? Sit down and you can strap yourself in.

And in she hops. This technique is so effective it feels like manipulation bordering on unethical. But if the only alternative is physical coercion, it's not so bad. Fortunately (or otherwise), the child eventually learns countermeasures, and it's much less effective by age 4. But by that age dialogue and mutual understanding largely replace the need for coercion.

Then I noticed an eerily parallel conversation going on the other side of the Atlantic:

Uncle SamMore war, more global warming, more bailouts for rich people, more oppression for the poor.
The PeopleNo, we want transparent, open and fair government!
Uncle SamReplublican or Democrat?
The PeopleUm .. Democrat, this time, please
Uncle SameHmm. Well, just this once, ok?

07 October 2008

HTML: Scroll table contents without scrolling headers

 

I stumbled upon this quite by accident: all you need do is put the content you want scrolled inside a tbody tag, with style='height:nn;overflow-y:auto' where nn is the height you want your content. The tr containing your headers goes outside this tbody. This has been obvious all along to people who understand CSS, but I'm only starting to get to grips with this stuff. Here's an example, hit view source to see how it works:
foobar
0x
1y
2z
3x
4y
5z
6x
7y
8z
9x
Beats a zillion lines of js and css to do the same thing, no? It works for Firefox 3, I haven't tested it elsewhere. If anybody out there still has IE, please let me know if it works! Update : if you want the whole table to scroll horizontally, too keeping the headers aligned with their columns (thanks, Olivier), put the it in a div with style='width:nn;overflow-x:auto'. Thus:
foobarbaz
000.00xxxtoto-titi
100.00yyytiti-didi
200.00zzzdidi-dodo
300.00xxxdodo-toto
400.00yyytoto-titi
500.00zzztiti-didi
600.00xxxdidi-dodo
700.00yyydodo-toto
800.00zzztoto-titi
900.00xxxtiti-didi
It's not so pretty - the vertical scrollbar is visible only if you've scrolled horizontally all the way to the right. But given that you can scroll with the keyboard or mouse wheel, perhaps that's not such a terrible thing ...

Make Freemarker work with Prototype's Ajax.Request

The popular Ajax.Updater from Prototype is great for getting little bits of HTML back from your server and sticking them in your client's page somewhere. But Prototype has some other tricks hidden up its sleeve. The Ajax.Request utility (upon which Ajax.Updater is based) has a very nice feature: if the response comes with content-type "application/javascript" (or equivalent), it evaluates the response body as if it were javascript code. Imagine that: the server can send any arbitrary piece of code back to the client to be executed on the client's machine.

Any kind of ajax-based state change could use this technique: a login, a deletion, an insertion. For example, after a deletion, you might wish to return this response:

widget-deleted.ftl
${res.setContentType("application/javascript")};
alert('widget ${widgetId} successfully deleted');
$('div_for_widget_${widgetId}').remove();

- to provide feedback to the user in two ways: an alert, followed by the disappearing of the dom element representing the deleted object.

You might even find this technique useful to resolve the ages-old dilemma of whether to perform input validation on the server or on the client. Up to now, the correct answer has been (frustratingly) "both". But now you can avoid duplicating validation code in javascript: instead you have a javascript response that provides server-side validation-failed feedback to your user.

Here's another example, for an application that takes comments, and requires a non-empty comment. The first indicates a successful comment submission:

comment-ok.ftl
${res.setContentType("application/javascript")}
alert("Your comments have been noted. Thank you.");
$('commentForm').hide();

And the second, failure:

comment-failed.ftl
${res.setContentType("application/javascript")}
alert("You didn't enter a comment!");

Your controller decides which response template to evaluate after having performed the relevant validation. Webwork/Struts2 makes this decision based on its "struts.xml" configuration and the outcome of your action.

The first line in each of these examples sets the content type of the response so that Prototype knows to interpret it as code. The MVC framework you are using should have inserted some variable in the Freemarker context to represent the response - in the case of Webwork/Struts2, it's called "res".

Don't go overboard with Ajax though - keep in mind Ajax breaks bookmarkability and browsers' back/forward buttons. Distinguish between requests that access and display resources - a bookmarkable url is nice here, and actions that modify state on the server - Ajax.Request might be useful here, unless the state change should take you to a new page.

Let me know how this works for you!