Convert Generic Objects into Class Instances

| 3 Comments | No TrackBacks

This question has come up a lot on FlexCoders recently, so I wanted to offer to the community a generic solution to convert plain old vanilla objects into full-fledged class instances.

I had originally developed this solution to be used with the JSON library that I made for the Adobe Labs Corelib project, but it's really an all-purpose solution. Essentially, my utility method allows you to turn any remote service that returns plain old ActionScript objects (like JSON, WebServices, etc) into a service that returns typed class instances, much like RemoteObject.

This makes it easier to employ the ValueObject pattern... instead of getting back an object with some properties attached, I can convert that object into, say, a Book ValueObject. The Book then is easier to work with because I get IDE and compiler support from strong typing, and it also speeds up the code execution since accessing values in typed objects executes faster than in non-typed objects.

You can download my ObjectTranslator, and its test cases, here. (MIT License)

UPDATE: October 1 2011: I've moved the code from a .zip download to a GitHub repository at https://github.com/darronschall/ObjectTranslator. This makes it easy to download the code as a .zip file and in the spirit of social and sharing, allows others to freely contribute.

Usage is as follows:

import com.darronschall.examples.vo.Book;
import com.darronschall.serialization.ObjectTranslator;

// Define an object with properties that mimic the variable names
// inside of the Book class
var bookObj:Object = { title: "My Book title", pageCount: 10, inLibrary: true };

// Convert the generic object into an instance of the Book class
var book:Book = ObjectTranslator.objectToInstance( bookObj, Book ) as Book;

Yup, it's really that simple.

Unfortunately, things get a little more complicated when you have nested ValueObjects. I didn't take the time to make my method recursive, so it's up to you to first convert the nested objects into instances, and then convert the top level object into an instance. It's a little more work that can avoided by some recursion. I've outlined what the algorithm would look like inside of the code, I just haven't had the time to write it yet.

import com.darronschall.examples.vo.Book;
import com.darronschall.examples.vo.Student;
import com.darronschall.serialization.ObjectTranslator;

var studentObj:Object = { firstName: "test first",
					  lastName: "test last",
					  favoriteBook: { title: "Favorite Book!" }
					};	
								
// First we need to convert the nested objects to classes
studentObj.favoriteBook = ObjectTranslator.objectToInstance( studentObj.favoriteBook, Book );
		
// Convert the student object to a Student class
var student:Student = ObjectTranslator.objectToInstance( studentObj, Student ) as Student;

So, to summarize, the objectToInstance method allows JSON and WebService services to return true class instances from the server, making them behave like RemoteObject and allowing developers to more easily employ the ValueObject pattern. Use the objectToInstance method on the object that the service returns, and then use the converted instance elsewhere in your code.

Those who are curious about the implementation will get a kick out of the simplicity of my algorithm. Essentially, all I'm doing is constructing an AMF packet with the class name and the object property values, then doing a byteArray.readObject() to convert the AMF packet into a class instance. The code is fairly well commented so you can follow along easily. I'd like to think this is one of those "so simple it's brilliant" type of moments...

Have fun, and let me know if you run into any issues!

Tags: , ,

No TrackBacks

TrackBack URL: http://www.darronschall.com/mt/mt-tb.cgi/129

3 Comments

Thanks, that is a really smart hack :)

I've found a secondary back-to-front use for this - you can turn user-defined classes into Objects and iterate through the class properties. Normally you can't do this. This is very useful for serializing a class to JSON data.

Actionscript does not allow enumeration of user-defined classes so this is a good shortcut.

Using byteArray.readObject() to convert the AMF packet into a class instance" is very kewl!

Really nice hack. Really nice contribution.

You have also highlighted the problem with JSON... no schema information. So nested objects have no runtime-defined class mappings. Developers must "know" the relationships. This impacts any robust recursive conversion.

One possibility is for your parser must 'analyze' recursively the parent Flex class for child class information, then use that information with the nested JSON object....

Leave a comment



About this Entry

This page contains a single entry by darron published on October 29, 2006 4:01 PM.

The Cookbook is here... was the previous entry in this blog.

Compile ActionScript in ActionScript is the next entry in this blog.

Find recent content on the main index or look in the archives to find all content.

Archives

OpenID accepted here Learn more about OpenID
Powered by Movable Type 5.02