My Stuff
Email
Twitter
Front Page
Presentations
Projects
Music
Favorite Quotes

Respect
Vincent Foley-Bourgon
Sam Griffith
LeRoy Mattingly
Colin Putney
Matt Secoske
Sam Tesla
Andres Valloud

Admiration
Leo Brodie
Avi Bryant
Alan Cooper
Steve Dekorte
Stephane Ducasse
Doug Engelbart
Eric Evans
Brian Foote
Martin Fowler
Paul Graham
Dan Ingalls
Alan Kay
John McCarthy
Steve McConnell
Peter Norvig
Niall Ross
Randall Smith
Gerald Jay Sussman
David Ungar
Rebecca Wirfs-Brock
...And So Many More...

My Amps
Squeak
JavaScript
Scheme
Java
Corman Lisp
Ruby
Dolphin Smalltalk
Cincom Smalltalk
Self

Archives
05/01/2003 - 06/01/2003
06/01/2003 - 07/01/2003
07/01/2003 - 08/01/2003
08/01/2003 - 09/01/2003
09/01/2003 - 10/01/2003
10/01/2003 - 11/01/2003
11/01/2003 - 12/01/2003
12/01/2003 - 01/01/2004
01/01/2004 - 02/01/2004
02/01/2004 - 03/01/2004
03/01/2004 - 04/01/2004
04/01/2004 - 05/01/2004
05/01/2004 - 06/01/2004
06/01/2004 - 07/01/2004
07/01/2004 - 08/01/2004
08/01/2004 - 09/01/2004
09/01/2004 - 10/01/2004
10/01/2004 - 11/01/2004
11/01/2004 - 12/01/2004
12/01/2004 - 01/01/2005
01/01/2005 - 02/01/2005
02/01/2005 - 03/01/2005
03/01/2005 - 04/01/2005
04/01/2005 - 05/01/2005
05/01/2005 - 06/01/2005
06/01/2005 - 07/01/2005
07/01/2005 - 08/01/2005
08/01/2005 - 09/01/2005
09/01/2005 - 10/01/2005
10/01/2005 - 11/01/2005
11/01/2005 - 12/01/2005
12/01/2005 - 01/01/2006
01/01/2006 - 02/01/2006
02/01/2006 - 03/01/2006
03/01/2006 - 04/01/2006
04/01/2006 - 05/01/2006
05/01/2006 - 06/01/2006
06/01/2006 - 07/01/2006
07/01/2006 - 08/01/2006
08/01/2006 - 09/01/2006
09/01/2006 - 10/01/2006
10/01/2006 - 11/01/2006
11/01/2006 - 12/01/2006
12/01/2006 - 01/01/2007
01/01/2007 - 02/01/2007
02/01/2007 - 03/01/2007
03/01/2007 - 04/01/2007
04/01/2007 - 05/01/2007
05/01/2007 - 06/01/2007
06/01/2007 - 07/01/2007
07/01/2007 - 08/01/2007
08/01/2007 - 09/01/2007
09/01/2007 - 10/01/2007
10/01/2007 - 11/01/2007
11/01/2007 - 12/01/2007
12/01/2007 - 01/01/2008
01/01/2008 - 02/01/2008
02/01/2008 - 03/01/2008
03/01/2008 - 04/01/2008
04/01/2008 - 05/01/2008
05/01/2008 - 06/01/2008
06/01/2008 - 07/01/2008
07/01/2008 - 08/01/2008
08/01/2008 - 09/01/2008
10/01/2008 - 11/01/2008
01/01/2009 - 02/01/2009
09/01/2009 - 10/01/2009

Feed

Add this feed to a running copy of BottomFeeder

Sunday, December 03, 2006

Jakarta Commons: Collections

 
Lately, I've been using the Jakarta Commons Collections library quite a bit since I've been back in Java 1.4 land. The library gives you everything you're used to with iteration methods available in Ruby and Smalltalk (do, collect, select, detect, etc). But, with the verbose and cumbersome syntax of anonymous methods the point of what you're trying to do gets lost. For example,
Collection activeAccounts=CollectionUtils.select(someAccounts, new Predicate() {
public boolean evaluate(Object object) {
return ((Account)each).isActive();
}
});
Wouldn't this be nicer:
Collection activeAccounts=CollectionUtils.select(someAccounts, Account.BY_ACTIVE);
One, it's lot less typing and reads much better in your logic. I've put the Predicate on the Account class. I really liked doing it this way and made my code read much more cleanly. Also, by having the Predicates defined on the objects that they were operating on, it made it easier to find which Predicates had already been defined. Everyone wins right? Well, no, I started using the same technique for Closures and Transformers too. My objects started to get crowded because I look putting my public static declarations at the top. Now, what to do?

Well, I was speaking to Matt Secoske one morning, we naturally started to discuss my dilemma of growing predicates and he had a simple answer: Put them in inner classes. At first, I scoffed at the idea, but after thinking about it, I came up with the following code:
public class Account {
public static final Predicates BY=new Predicates();

//Class stuff...

//Put this at the bottom of the class
static class Predicates {
public Predicate active() {
return new Predicate() {
public boolean evaluate(Object each) {
return ((Account)each).status.isActive();
}
};
}
}
}
I have no idea why I didn't like the idea at first. But now, my client code looks like this:
Collection activeAccounts=CollectionUtils.select(someAccounts, Account.BY.active());
The client reads the same, but now, I've gotten the implementation of the predicates out of the way. Everyone wins. I also put my transformers in their inner class named AS and one for closures called EACH. The important thing is that I keep meaningful information at the top and my client code reads well. Another thing to note is that now I can hide more information and expose less. You would be amazed at how much data is exposed in predicates. Yet, another nice side effect.

You will also notice that in the resulting code that I used a status instance variable to figure out if it was active so that I didn't have to duplicate the protocol of the status object through the Account object. My code has been getting simpler and it's been shocking me.

The point should always be to make the clients that use your objects life easier and more readable.

Comments
  • (kerrin said... ha ha. Travis Griggs said it using kerrin's account :) )

    "Wouldn't this be nicer:
    Collection activeAccounts=CollectionUtils.select(someAccounts, Account.BY_ACTIVE);
    "

    What would be nice is:

    someAccounts select: #isActive

    Load SymbolValue from the VisualWorks Open Repository and that's all you need. Or you can load HigherOrderMessaging from the same repository and write:

    someAccounts select isActive

    [This message brought to by the Knights of Square Brackets, an order that masters syntax in the interest of solving problems]

    By Blogger kerrin, at 12:41 AM   

  • Yes, yes, I'm not going to argue it's nicer in Smalltalk or Ruby. We all know that. But, for those of us slogging it out in the trenches of verbosity, I thought this might help. Java is a great challenge to write code that reads well. They made it a little nicer in 1.5 with Iterable and the new for loop. But, in Smalltalk, it's so easy.

    I wrote HOM as an exercise in Squeak named LazyCollections in SqueakMap. That project started out as a simple exercise in functional programming, but I realized how easy HOMs were to add to it. Smalltalk rules. By the way, I love the tag line at the bottom.

    By Blogger Blaine, at 9:13 AM   

  • I posted my take on it
    here
    .

    Basically, static methods on the account clean up the client code and don't expose the CollectionUtils dependency:

    Collection activeAccounts = Account.selectActive(someAccounts);

    By Blogger Jeff, at 6:48 AM   



Web hosting by ICDSoft

Metalheads Against Racism
This page is powered by Blogger. Isn't yours?


My Weekly Top 20 Artists