Tuesday, July 25th, 2006

Rediscovering Flyweight for Javascript

Category: Editorial, Programming

We posted about memory problems the other day (“the biggest Ajax problem” :-) and while it’s always good practice to clean up, another good practice is to avoid allocating excessive memory in the first place. To that end, I’ve recently been experimenting with the Gang Of Four Flyweight pattern within Javascript.

Flyweight works like this. Instead of creating an object for every entity, we only allocate a “Flyweight” object only for every type of entity. Because these Flyweight objects don’t have internal, object-specific, state, we have to pass a little context each time. It’s a compromise to cut down on memory. Flyweight often rears its head when you have some kind of object pooling (e.g. stateless session EJBs).

The pattern works well with Ajax apps, where the DOM already holds a lot of context, since we’re displaying that for the user. So I just need to pass in an element (or an element ID) as the context, and the Flyweight object will get the actual state of that element by reading its DOM properties.

To use the canonical blog example, we can have two kinds of comments – ManualComments and TrackbackComments. Assuming this is an Alpha blogger who gets 200 ManualComments and 50 TrackbackComments after posting that it’s cloudy outside, we would have a lot of objects to allocate if we did things the naieve way. And, of course, it would get a lot worse with a dynamic app that keeps creating and deleting objects, if there happened to be a memory leak (yes, which should ideally be avoided, but when you have a deadline and one browser or another isn’t playing nice …).

Instead of holding 250 Comment objects, we simply use two objects – a ManualComment object and a TrackbackComment object. Each div representing a manual comment would then have a “comment” property referencing the (singleton) ManualComment object. Alternatively, we might prefer to implement some kind of factory that accepts an element and gives us back either the ManualComment object or the TrackbackComment object. So when the user clicks a “Mark As Spam” button inside the div, we have a means of getting back either a ManualComment or a TrackbackComment, and we can then call comment.markAsSpam() on it.

We might also have a Comment “superclass” to encapsulate common property (relying on prototype chaining supported by Dojo/Prototype/Base/etc libraries). Unlike Java-style Flyweights, we don’t have to declare abstract methods though; JS being dynamic, we can rely on Duck Typing, so it’s possible that our ManualComment and our TrackbackComment will each have their own markAsSpam() method, but Comment (if it exists at all), will have no such thing.

Posted by Michael Mahemoff at 6:05 pm

3.9 rating from 23 votes


Comments feed TrackBack URI

Interesting Finds: July 25, 2007

Trackback by Jason Haley — July 25, 2006

Great work!

Comment by Ajaxium — July 26, 2006

Another approach to this is to use Object pooling. Instead of destroying the object you just store him in a pool for later use and when you need another instance of it you will just ask the pool for providing one.

Comment by Remus Stratulat — July 27, 2006

Leave a comment

You must be logged in to post a comment.