http://qs1969.pair.com?node_id=94904


in reply to Class::Flyweight - implement the flyweight pattern in OO perl

Interesting idea.

I share your concern over the "clone" method. I would be inclined to name the two main methods "instantiate" and "access". So your example would look like:

package MyPackage; use strict; use Class::Flyweight; my $flyweight = Class::Flyweight->new(); sub new { return $flyweight->instantiate(bless {}, shift); } sub get_name { my $self = $flyweight->access(shift); return $self->{name}; }
etc. I would also export a private DESTROY method to do the cleanup. There should be no reason for classes using this to rewrite DESTROY all of the time by default.

But while I like the idea, I look at it and I have to wonder what you have really added to what you get from hand-rolling:

package MyPackage; use strict; my %instance; sub new { my $class = shift; my $obj = {}; my $name = "$obj"; $instance{$name} = $obj; return bless $name, class; } sub get_name { my $self = $instance{shift(@_)}; return $self->{name}; }
etc. Well you have gained something, but I am not sure that the overhead of adding a method call to every method call is enough for me.

The direction that I would be inclined to go instead is to make your encapsulation weaker. Instead of exporting methods that can be used to implement a flyweight, accept a hash of package translations and implement each class in terms of the translated one, with a shared lexical scope. That way the flyweight is implemented by having an autogenerated class proxy for a private implementation. This way someone could develop with encapsulation, and then before making the code production could change their package names and drop the flyweight protection for speed.

This would involve writing and evaling code which would wrap methods with AUTOLOAD. The protection would be less (after all someone could easily take a look at your actual package names). But it would still provide something and it now is clear to me what value is added over handrolling my own flyweight implementation (better performance in production).

A note. The question was asked of how to handle inheritance. Well yours handles that by allowing you to explicitly copy the private flyweight object to each inherited class. My suggestion would take more thought on your part. Perhaps the private packages when you set up the flyweight mapping will get treated specially, so the only thing that changes when you go to production is that you eliminate the flyweight and change package names.

As for your other question, I think this is neat but I am not sure that it is solving a pressing problem for me. So I probably wouldn't use it. But I would put this in my list of neat things to keep in mind just in case, even though I don't have a specific use in mind right now...