1/31/2008

Objects as Functions

I've been wanting to write this post for sometime now. It just takes my so long to write a post, usually because of their length, that I don't do it as frequently as I should. I promised more articles in my last post so here we go.

Over the last couple of years I've been learning other languages particularly Javascript and Ruby. I really like Javascript as a language, API could use some help. I love Ruby's style of meta-programming and the fact that everything is an object. What I'm really jealous is how powerful a single function in these languages can be. For example in javascript it's easy to create widgets with Ext.js:


var button = new Ext.Button( 'okButton', {
text: "OK",
click: function( evt ) {
alert("Hey!");
},
"class": "myCssClass"
} );


In Swing this would be 25 lines of setter methods to customize components (OK maybe I'm exaggerating a little). Or in Ruby active record is just so simple and elegant with things like:


books = Book.find( :all, :condition => [ "where pubdate > ?", pubDate ], :include => [ :tags, :comments ] )


The ability to hand in optional arguments regardless of position turns simple functions into really expressive mini languages. Dare I say DSLs. I really miss these features when I have to use Java. Since Java opted for the C++ route of data structures. Data structures live in the API, and not the language, it's difficult for us to mimic this type of power.

I remember reading the Javascript Bible several years ago, and in there is a chapter titled "Functions as Data". And, the author is trying to show how functions can be assigned to variables, and passed around the system such one part of the program is unaware of which exact function it's calling. He's trying break the stereotype of functions being just actions, and show you how functions can be data as well. It's a good chapter for any developer.

This got me thinking about stereotypes we have about other languages. In Java we, all too often, get stuck thinking of our objects as largely data with some marginal functions mashed in to manipulate or manage that data. We usually create huge single instance, infinite lifetime objects that then do all the heavy lifting. However, what if we created objects that lived really only for a small period of time just to perform small functions? In fact what if we took what we would normally write as a function and turned it into an object. How would that change what we could express?

Now we need a problem to practice our idea on. Let's say we want to build a simple email utility because I think everyone who has worked on a web application in the past has had to send out email. For example, say we want to send an email from the site when people register to welcome them to the system, or when they forget their password. And, as you know Javamail, while a pretty good general purpose API, is very verbose to use. So let's say we create some utility method for sending email:


public MailHelper {
public static MimeMessage createEmail( String to, String from, String subject, String template ) {
}
}


The idea of this method is that we give it the to, from, subject, and a template file to use for the body, and it returns a MimeMessage, which is a Javamail class. It's basically an object representing an email. The template is either a Velocity or Freemarker template. I'm going to use Velocity in this example. If you're not familiar with these libraries they're really simple. They take in text like:


Hi $name,

Welcome to my cool new website. Thanks for taking the time to register with us. We're so glad to call you a member. Here is your password: $password in case you forgot, and here are some great places to get started $interestingPlace.

Thanks

The Man


And replace all of the "$" references with something you assign to them. So in your program you might say "name"="Charlie", and "password"="wouldnt you like to know", and "interestingPlace"="Tahiti". If you've used properties in Ant it's really a similar concept. It's not rocket science.

Now back to our utility. The problem with our utility is that we need a way to set all of those interesting variables that we'll substitute into our template. But, how do we do that with our single static method?

In Javascript or Ruby they might just pass a hash map like:


function createEmail( to, from, subject, template, bindings ) {
bindings = bindings || {}; // these notation is used for optional arguments.
}


What's cool about the function above is that if you don't have any bindings, just don't include it. Javascript doesn't require you pass all of the arguments to the function so the first line just happily sets bindings to empty object if they aren't specified.

So if we copy this in Java we'd add a HashMap onto our arguments:


public MailHelper {
public static MimeMessage createEmail( String to, String from, String subject, String template, Map bindings ) {
}
}


Then our usage would be something like:


public static void main( String args[] ) {

Map bindings = new HashMap();
bindings.put("name", "Unsuspecting Luser");
bindings.put("password", "wouldnt you like to know" );
bindings.put("interestingPlaces", "Tahiti" );

MimeMessage message = MailHelper.createEmail( "ycnangerp1@hotmail.com", "kevben@coldmail.ca", "Hello New Member", "email.vm", bindings );
}


Now I don't know about you, but that kinda code drives me nuts. It's so verbose, and
boring! The Javascript and Ruby versions of this are so much more fun. Now what if we wanted to add some attachments, CC some people, or add HTML and text versions of the email? Our poor little static function just can't hang. What we need is something better.

If you're still not convinced that statics aren't up for this consider that I'm leaving out some very important architecture here. Particularly, I need a VelocityEngine instance inside the static function in order to evaluate the template. Now I have to make a choice. One I make a simplifying assumption that I only need one instance of VelcoityEngine and initialize it in the static utility. That would mean I give up on the ability to have multiple template locations, or mail servers, etc. This would make it hard to unit test. It also makes reusing this utility harder because everything is hardcoded structurally. And, singleton's don't help this! The other choice is force the user to manage of the data this static utility needs, but I think that would compromise the ease and usefulness of the utility. Kinda of like well geez if you're going to make me do all of that I might as well just do it myself. Both of them get us into ugly Java.

What if we take our function and turn it into an object? I'm going to approach this from the outside interface, and then show the implementation:


public static void main( String[] args ) {

Emailer emailer = new Emailer();

MimeMessage mime = emailer.email("ycnangerp1@hotmail.com", "Hello New Member", "email.vm" )
.bind( "name", "Bad Spammer" )
.bind("password", "wouldnt you like to know")
.bind("interestingPlaces", "Hell" )
.toMail();
}



Look at that! Much easier to use. Notice how I don't have to create a seperate HashMap. Our new object provides this for us so binding is completely optional. If the email you're sending doesn't have any bindings then just don't call the bind() method. Also notice that emailer instance has a email() method to create an email. It almost reads like English. It also scales nicely for other types of data like attachments, or CC'ing:


public static void main( String[] args ) {

Emailer emailer = new Emailer();

MimeMessage mime = emailer.email("ycnangerp1@hotmail.com", "Hello New Member", "email.vm" )
.bind( "name", "Unsuspecting Luser" )
.bind("password", "wouldnt you like to know")
.bind("interestingPlaces", "Tahiti" )
.cc( "manager@spambot.com" )
.attach( stockHypeImage )
.toMail();
}



I'm using email addresses of known spammers to increase the chances spam bots will pick them up and blast emails at them.

If you'll notice I moved one parameter out from the first function: the from parameter. I'll add this back in at a later point in time. You'll also notice the toMail() method. Since we're making multiple calls we'll need a function to end the transaction or kick off the action. I'm going to enhance the version of the code below to also send the email instead of just creating it. I'm not going to implement the toMail() method since sending is the ultimate goal. So now let's look at the code for implementing this kinda class:


public class Emailer {

private static final Logger logger = Logger.getLogger(Emailer.class);

private String from;
private String url;
private Properties mailProperties;
private VelocityEngine engine;

public Emailer( VelocityEngine anEngine, Properties mailProps, String from, String url ) {
this.engine = anEngine;
this.mailProperties = mailProps;
this.from = from;
this.url = url;
}

public Email email( String to, String subject, String mailTemplate ) {
return new Email( to, subject, mailTemplate );
}

public Email email( String to, String subject, String mailTemplate, String htmlTemplate ) {
return new Email( to, subject, mailTemplate, htmlTemplate );
}

public class Email {
private String to;
private String subject;
private String textTemplate;
private String htmlTemplate;
private Map params;

private Email() {
this.params = new HashMap();
if( url != null ) {
this.params.put("website", url);
}
}

public Email(String to, String subject, String textTemplate) {
this();
this.to = to;
this.subject = subject;
this.textTemplate = textTemplate;
}

public Email(String to, String subject, String textTemplate, String htmlTemplate) {
this();
this.to = to;
this.subject = subject;
this.textTemplate = textTemplate;
this.htmlTemplate = htmlTemplate;
}

public Email bind( String key, Object obj ) {
params.put( key, obj );
return this;
}

public void send() {
try {
Session session = Session.getInstance( mailProperties );
MimeMessage message = new MimeMessage( session );

message.setRecipient( MimeMessage.RecipientType.TO, new InternetAddress( to ) );
message.setFrom( new InternetAddress( from ) );
message.setSubject( subject );

if( htmlTemplate == null ) {
message.setText( renderTemplate( textTemplate ) );
} else {
String text = renderTemplate( textTemplate );
String html = renderTemplate( htmlTemplate );

MimeMultipart part = new MimeMultipart("alternative");
part.addBodyPart( createBody( text,"text/plain") );
part.addBodyPart( createBody( html,"text/html") );

message.setContent( part );
}
message.saveChanges();

Transport transport = session.getTransport("smtp");
transport.connect();
transport.sendMessage( message, message.getAllRecipients() );
transport.close();
} catch( Exception mex ) {
logger.error( "There was an problem emailing: " + subject + " to: " + to, mex );
}
}

private BodyPart createBody(String text, String mimetype) throws MessagingException {
MimeBodyPart body = new MimeBodyPart();
body.setContent( text, mimetype );
return body;
}

private String renderTemplate( String template ) throws Exception {
StringWriter writer = new StringWriter();

Template tmpl = engine.getTemplate( template );
VelocityContext context = new VelocityContext( params );
tmpl.merge( context, writer );
return writer.toString();
}
}
}


The two interesting methods are the Emailer.email() methods. The two versions are for sending text only emails, or multipart HTML emails. At the start it's really quite simple. Invoking email() creates an Email instance which is an inner class for the Emailer. At that point you can call bind() method for every object you want to bind into the template. Notice how bind() returns the Email instance allowing you to chain method calls. Finally once you're done call send() to actually send the email. This was something that you couldn't do with the static method. For one it was too complex to configure through a single method call, and you're static method would have to have access to java properties, velocity engine, etc. By limiting our interaction to statics we force our users to take on more responsibilities. In the static case the user has to use some other utility to send the email. Either we have to force user to manage the architecture by gathering up the velocity engine instance, java mail properties, etc. Or we hard code it with statics in such that our tool will only work for a single velocity engine, from, and java mail properties. Neither is very helpful. One doesn't do enough to make it helpful, and the other limits our architecture and impacts how we can reuse it.

The Emailer class is also split into two parts. The outer class which holds all of the architectural/configuration items (velocity engine, java mail properties, etc). By splitting the code this way those portions can be configured at some place else in the code, say at application initialization, and the parts of the code that need to send email can be blissfully unaware of the architecture used to do so. This outer class acts as the glue between the java mail settings, velocity engine, and simple data like the email address of the author. It's really similar to functional language technique of currying functions.

The second part is the inner class Email. Using an inner classes allows us to create an instance that holds temporary state (i.e. bindings, the template for a specific email, to, subject, etc), but still has access to long living state (i.e. mail host, properties, velocity engine, etc). If we mixed the two inside the Emailer class we couldn't share that across multiple threads. Notice there's no setter methods on Emailer. That means once the Emailer is created other threads can't modify the internal state of it. It's immutable so it's safe to share the Emailer across multiple threads. This pattern allows Emailer to be shared, while Email instances only live on the stack of each Thread. There by separating data being written to (i.e. specifics for sending a single email) from the data that's not changing (i.e. the architecture of sending emails). Safety without synchronizing!

Notice how what started out as our verb function, createEmail(), and turned into a Noun, Email, that acted like a verb. That's usually what happens when you move from static utility methods to active function Object. For lack of a better term.

What's cool about this approach is our Emailer class acts more like a complex function like we saw in Javascript and Ruby. In a single line we easily send an email that requires potentially complex optional data. In addition it allows clients of this class to focus only on sending email, and not worry about the details of how that email is actually sent. Since we're in Java our function Object can tell the user all the options you can call on it with our IDE's code completion feature. Something Ruby and Javascript can't do reliably enough to be useful. With those scripting languages you're relying on the documentation to tell you the specific options of the function.

This pattern in Java looks more like Smalltalk to me. Your functions can end up looking very english-like. By using method chaining and inner classes we can get the same power without having to sacrifice the compact, expressiveness of functions we enjoyed with Javascript and Ruby. Not only did we improve the code's reusability, but we delivered more features by switching from static method to function object. We went from just being able to create the email to actually creating and sending it using objects as functions. In the end, we can now create very powerful single line "functions" just like those scripting languages by using the one construct Java does well. Objects.

Now as I promised da code. This example create a sub directory called templates under your current working directory, and put a test.vm template in there. Copy the template text above, and it will work:


package mail;

import org.apache.log4j.Logger;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.Template;

import javax.mail.*;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.InternetAddress;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.io.StringWriter;

public class Emailer {

private static final Logger logger = Logger.getLogger(Emailer.class);

private String from;
private Properties mailProperties;
private VelocityEngine engine;

protected Emailer() {
}

public Emailer(VelocityEngine engine, Properties mailProperties, String from) {
this.engine = engine;
this.mailProperties = mailProperties;
this.from = from;
}

public Email email( String to, String subject, String mailTemplate ) {
return new Email( to, subject, mailTemplate );
}

public Email email( String to, String subject, String mailTemplate, String htmlTemplate ) {
return new Email( to, subject, mailTemplate, htmlTemplate );
}

public class Email {
private String to;
private String subject;
private String textTemplate;
private String htmlTemplate;
private Map params;

private Email() {
this.params = new HashMap();
}

public Email(String to, String subject, String textTemplate) {
this();
this.to = to;
this.subject = subject;
this.textTemplate = textTemplate;
}

public Email(String to, String subject, String textTemplate, String htmlTemplate) {
this();
this.to = to;
this.subject = subject;
this.textTemplate = textTemplate;
this.htmlTemplate = htmlTemplate;
}

public Email bind( String key, Object obj ) {
params.put( key, obj );
return this;
}

public void send() {
try {
Session session = Session.getInstance( mailProperties );
MimeMessage message = new MimeMessage( session );

message.setRecipient( MimeMessage.RecipientType.TO, new InternetAddress( to ) );
message.setFrom( new InternetAddress( from ) );
message.setSubject( subject );

if( htmlTemplate == null ) {
message.setText( renderTemplate( textTemplate ) );
} else {
String text = renderTemplate( textTemplate );
String html = renderTemplate( htmlTemplate );

MimeMultipart part = new MimeMultipart("alternative");
part.addBodyPart( createBody( text,"text/plain") );
part.addBodyPart( createBody( html,"text/html") );

message.setContent( part );
}
message.saveChanges();

Transport transport = session.getTransport("smtp");
transport.connect();
transport.sendMessage( message, message.getAllRecipients() );
transport.close();
} catch( Exception mex ) {
logger.error( "There was an problem emailing: " + subject + " to: " + to, mex );
}
}

private BodyPart createBody(String text, String mimetype) throws MessagingException {
MimeBodyPart body = new MimeBodyPart();
body.setContent( text, mimetype );
return body;
}

private String renderTemplate( String template ) throws Exception {
StringWriter writer = new StringWriter();

Template tmpl = engine.getTemplate( template );
VelocityContext context = new VelocityContext( params );
tmpl.merge( context, writer );
return writer.toString();
}
}

public static void main(String[] args) throws Exception {
Properties p = new Properties();
p.setProperty("file.resource.loader.path", "./templates");

VelocityEngine engine = new VelocityEngine( p );
engine.init();

String from = "author@yourcompany.com";

Properties javamailProps = new Properties();
javamailProps.setProperty("mail.host", "!YOUR_MAIL_HOST");
javamailProps.setProperty("mail.user", "!YOUR_MAIL_USER");
javamailProps.setProperty("mail.password", "!YOUR_MAIL_PASSWORD");
javamailProps.setProperty("mail.port","25");

Emailer emailer = new Emailer( engine, javamailProps, from );

emailer.email("person@somedomain.com", "This is a test", "test.vm")
.bind("name", "Chuck")
.bind("password","KutzMutz")
.bind("interestingPlaces","Tahiti")
.send();
System.out.println("Email sent!");
}
}

1/11/2008

You don't know Jack about Objects!

I have been conducting phone interviews over the last few days, and I feel less positive about the computer programmers out there. Every candidate out there has Object Oriented Design on their resume in spite of the fact they can't define polymorphism or worse encapsulation! If you can't define polymorphism or encapsulation without resorting to examples then you can't write Object Oriented Design as one your skills. You don't even know what object oriented is!

The world is full of what I term imperatives. Essentially, it's the style of code you in most imperative languages like Fortran, C/C++, and sometimes Perl (well that's if you actually understand someone else's Perl). Object oriented programming is a total shift in the way you think. It's not just a language, and to effectively use it well, you have to see others using it effectively. And, that's so hard because so much code out there is imperative at its core.

Loads of static utilities classes, singletons, and objects with only getters/setters on it litter the landscape of the mainstream. If you've ever written an entity object with only getter/setters then each entity has a companion manager class voila that's how imperatives roll. What's the big deal? The big deal is you're not getting the benefits of true OO. I recently re-read the white XP book, and in there Kent Beck talks about the cost of change, and while you don't need object orient languages to lower the cost of change. "However, in my experience the cost of change rises more steeply without objects than with objects." This has been my experience too. Object oriented languages keep the cost of change lower than other imperative equivalents. But, only if you use them correctly. Now why would Kent say that?

He's referring to encapsulation, particularly the fact that certain parts of your program should not interact with each other. That's precisely what happens in object oriented programs. What makes changing programs hard, or worse scary, is the dependencies between parts of your program. It's easier to modify your program if your changes aren't going to affect some other unrelated part. Most people think of encapsulation as effective use of access modifiers like public, protected, and private. Access modifiers are the micro-level idea of encapsulation. There exists a macro-level version of encapsulation in how your objects communicate with each other. This macro level is more important than the micro level.

Object oriented languages typically work by calling methods on instances. That means if you don't have a reference to an instance then you can't invoke methods on that object. This fact forms the basis for the macro-level concept of encapsulation. It's all about these references between objects. This macro level encapsulation more commonly referred to as architecture. A great example of this form of encapsulation is the MVC pattern.

How does the MVC model help with maintenance? Well I think it comes from understanding how to make effective reuse of your code. According to the MVC pattern Views should be empty shells waiting to be filled. Void of any business logic. Controllers responsibilities are interacting with the model, choosing which view should be rendered, and binding the model to the view. The interesting part of this pattern is that model objects are used by the view, and the controller. It's this property that makes the model so important because it's the one portion of the system that can be accessed from any other part of the program without increasing your cost of change.

Here is an example that I recently had. I had two Controllers that were serving up thumbnails of movies, and pictures. Interestingly, I needed to stream the bytes of those images over the response. The one thing that's common between these two controllers is that they both use the Thumbnail object. Imperative systems you'll find some sort of ThumbnailUtil.send() method that will share between the Controllers to do this. Ugggh. So there is the duplication and separation that begins to creep into your system when you start programming in an imperative style in an object oriented language. It would be trivial to reuse that logic if it belonged to my Thumbnail object:


public ModelAndView handleRequest( HttpServletRequest request, HttpServletResponse response ) {
Thumbnail thumbnail = thubmbnailService.loadThumbnail( thumbnailId );
thumbnail.send( resposne.getOutputStream() );
return null;
}


It's that simple! For one you're using fewer classes. The send() method is accessible to any controller that can access a thumbnail. Your model objects should have behavior, and this really goes along with any language. I started getting this idea in Java, and I started to really crystallize when I was doing Ruby/Rails. You notice two things. It's easy to reuse logic, and quick to build functionality because after a while you build up a language that models your business logic. Things are now very high level uses of these basic pieces of business logic. This is exactly like Paul Graham's discusses in Programming Bottom-Up.

Another side effect of this is that it's easy to test. In Rails they went great lengths to try and test your model, controller and model, and full integration view, controller, and model. Notice how Rails doesn't try to separate Controller from model which I think is very practical approach. But, the first level of unit testing is testing the model alone. If you're business logic is pushed down into that level it's much easier to test it than if it's inside the controller. You don't need the model and the controller so there's less dependencies you have to initialize and setup in your test environment. The more logic you can test in your model, the more coverage your getting, and the more robust your application will be.

Another example I recently ran into of more static loving imperative code was called ViewUtil. Our application is based on SpringMVC so someone added a ViewUtil class for retrieving the ModelAndView object required by SpringMVC. There was several portions of logic included in there for retrieving XML based views vs. HTML depending on properties in the HTTP request. Here are what this might look like:


public ModelAndView handlRequest( HttpServletRequest request, HttpServletResponse ) {
Model model = modelService.getModel( ... );

ModelAndView mv = ViewUtil.getView( request, "modelview" ).addObject("model", model).addObject("someParam", request.getParam("someParam");
mv.addObject( "model", model );
mv.addObject( "someParam", request.getParameter("someParam");
mv.addObject("someOtherParam", request.getParameter("someOtherParam");
return mv;
}


However, there are other problems that pertain to Views that end up inside our controllers because of the choice of using statics. For example, quite often when errors on our forms occur we have to copy parameters from the request coming in onto the ModelAndView leaving. Particularly, hidden fields on the form that don't belong inside objects. One of the problems with statics is that you can call them from anywhere. Using getView() method really only belongs in the Controller since that's the responsibility of the Controller, and not anywhere else.

Here is a more object oriented approach. One we move this method to retrieve views into our Controllers in a common super class. That way only our controllers can call it.



public class ApplicationController extends AbstractController {

protected View getView( String viewName, HttpServletRequest request, HttpServletResponse response ) {
... // all of our existing logic inside ViewUtil goes here.

ModelAndView mv = new ModelAndView(...);
return new View( request, mv );
}
}


Notice how in this example I'm not actually returning the ModelAndView class as the ViewUtil does. The reason for this is we're going to add our behavior to that object thus giving it the illusion of behavior on our ModelAndView class. So here is an example of our View class:


public class View {
private ModelAndView view;
private HttpServletRequest request;

public View addObject( String key, Object obj ) {
view.addObject( key, obj );
return this;
}

public View copyParams( String... params ) {
for( String key : params ) {
view.addObject( key, request.getParameter( key ) );
}
return this;
}
}


So here we're exposing just two simple methods. One is a delegated method to the addObject() on ModelAndView. Notice that I didn't include getters or setters for the HttpServletRequest or the ModelAndView. That's because they aren't really needed if you have a View object. Whatever sorts of code I need to do that operates on either of those objects I will put in my View object, and simply call that from my Controllers. I could even go further and add a new method to my ApplicationController.doRequest() that returns a View object instead of ModelAndView then that way my subclasses don't need a View.getView() to satisfy the Spring MVC method, and leave that to my ApplicationController.

Now I've created a easier way to handle things like copy parameters from my request to my view, and I don't need yet another static method on ViewUtil or something like that I just have smart View object. This technique is really the same has doing currying in functional languages. Instead of creating a scoped function we're created a scoped object. What's amazing about this technique is it allows one part of the program to transfer knowledge of a section of subsystems without another part of your program having to understand details about that subsystem. It's like a specialized context for another part of the program that's highly tailored to the needs at a point of time for only a short time.

Now on some level you can argue that ModelAndView object should have the copyParams method on it. But, it's not practical to think the needs of every program could be anticipated by our framework developers. It would be too cumbersome and difficult to understand because you'd need to separate out what you need from what you don't.

This illustrates that when you really stop thinking in statics and start thinking in terms of objects opportunities, that would be too cumbersome and repetitive in imperative land, open up in object oriented land. Also notice how I didn't use inheritance to accomplish this. This is the power of composition, and delegation. Inheritance is useful, but most often abused. Composition is an easy technique to learn, but seldom do imperatives ever use it effectively.