Skip to main content

Objects not Strings - transparent serialization over key/value pairs with proxies

Posted by timboudreau on August 16, 2008 at 12:55 AM PDT

I had an interesting thought the other day for a project I'm helping a friend with. Many things we deal with come in key/value pairs (URL parameters for instance). Why not immediately work with objects instead? There's a simple way...

Probably someone is already doing this - there are certainly enough serialization libraries out there. But here's the thought - I was thinking of URL parameters when doing this:

Say you have some parameters and you are expecting something like "id=128,name=foo,showDetails=true" - in some format like a Preferences object, a Wicket PageParameters or anything else that parses or aggregates key/value pairs. The InvocationHandler for the proxy transparently reads and writes the values based on the name of the method called (i.e. getFoo() means return the value for "foo" for whatever the storage is.

It's much nicer to work with objects than this sort of thing directly. So what if you could do something like this:

public interface Params {
   public int getId();
   public boolean isShowDetails();
   public String getName();
}

and then you call
Params params = new MySerializationStrategy().read (params);

Behind the scenes, you use dynamic proxies. MySerializationStrategy will simply look at the getters and setters, find the property names from them, and return an implementation that will implement the interface you passed in (you will never implement it yourself). You could even go nuts and serialize and, say, encode serialized objects as strings (not sure that's such a hot idea, but you could).

Poof - a bunch of ugly code becomes a nice friendly object. It has a few caveats (for example, an integer returning method with no key in the data needs to return something like -1).


beach.jpg

It's probably not so useful if there is one place the object with the key/value pairs is used. But if the result needs to be processed by multiple things, passing around an object is much nicer, and saves the code being littered with magical string keys. There is the price of a little reflection overhead, but there are cases where it would be useful.

I wrote a little proof of concept over Preferences objects which works nicely; you could do this over anything that boils down to key/value pairs. I wonder if the Wicket guys would be interested in a patch to PageParameters to do this.

Related Topics >>

Comments

Integrated into Wicket...

I got the following note this morning:
https://issues.apache.org/jira/browse/WICKET-2388?page=com.atlassian.jir...
which is a patch to Wicket's PageParameters class has been integrated into Wicket's source code. Woo hoo!

I do something very similar in this project here... http://code.google.com/p/xpathproxy/ I also wrote some interesting code in a private project that persisted interface-based proxy objects to name-value tuple tables in a database. interface ProfileProperties { Integer getMaxSearchResults(); void setMaxSearchResults(Integer max); } Using a dynamic proxy this would be persisted to a table like... PROFILE_ID | PROP_NAME | PROP_VALUE 6 | "maxSearchResults" | 100 It wasn't too difficult to write by leveraging the built-in PropertyEditors that Spring has available.

Keep in mind, I said potentially ;) "As a rule, objects should not be accessed reflectively in normal applications at runtime. There are a few sophisticated applications that require reflection. Examples include class browsers, object inspectors, code analysis tools and interpretive embedded systems.". However, he also mentions that reflection is appropriate for use in RPC systems to eliminate the need for stub compilers. This is, effectively, what you are doing albeit to a different effect.

> it violates the established norms of the static Java language I don't follow... If you're going to pass the result around, it's probably being parsed into a Java object anyway. What does doing it in one place, behind the scenes violate? (Although I'll be the first to agree you don't want your code full of this stuff - it definitely makes debugging harder [e.g., exception in Proxy6 unknown source]). I only have the original version of Effective Java (not to mention I'm in Seattle and the book is in Massachusetts), so I don't know what you're citing there.

You can do seemingly magical things with a dynamic proxy, but this is not one I've heard of before. Very KISS, I like it although potentially it violates the established norms of the static Java language (Effective Java SE, item 53).

Are you talking about what Struts does with its FormBeans? With the only difference being that instead of supplying a class with getters and setters, you supply an interface with getters and setters?