I disagee that this is not a factory, I think he is hiding the mechanics behind an interface.
# this line specifies the backend class, but
# we don't need to know that, to us, its just
# a parameter
my $x = Thing->new( backend => 'A' );
# here we are accessing the backend object
# and calling do on it.
# This to me is the interface for creating the
# backend object (the "backend" method).
$x->backend->do();
Sure, since we can look at his code's innards we know that in calling backend we are actually just getting a string class-name, which we then use to call class methods with and not instance methods. But if he were to switch the code in backend to actually return a proper blessed instance, the "outside" code would likely not need to change. Now if he did this:
$x->backend->new()->do();
then I would tend to agree with you.
I'd say the OP is showing a behavior composition technique, like the GoF's Strategy pattern, expressed in proper Perl idiom.
I agree with you here, but I think if the OP had done this:
$x->do_backend();
It would be more in keeping with the pure GofF Strategy pattern. The inside from cover defines Strategy as:
Strategy
Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it.
Which I think is in some ways what the OP is doing. However when you look at the suggested implementation (here taken from page 315 (minus one Compositor concrete class to make it fit in 70 characters)):
+-------------+ +------------+
| Composition |<>---------------------->| Compositor |
+-------------+ +------------+
| Traverse() | | Compose() |
| Repair() | +------------+
+------^------+ |
| +---------------+-----+
| | |
_________|________________ +------------------+ +---------------+
| compositor->Compose() \| | SimpleCompositor | | TeXCompositor |
+-------------------------+ +------------------+ +---------------+
| Compose() | | Compose() |
+------------------+ +---------------+
you can see where things differ. He is not calling the Strategy algorithm from the Thing object. He is instead returning an object. Although again, since we can see his code's innards, we know it is really a class and not an instance, but that the magic of encapsulation for ya. To me this is why his code more resembles a factory-ish pattern.
Now if you look the at the inside cover defintion of Abstract Factory and Factory Method, you could say that his is not truely following either of these to the letter either.
Abstract Factory
Provide an interface for creating families of related or dependent objects without specifiying thier concrete classes.
Since he is not creating actual objects and (through the "backend" parameter in the constructor) he is asking the user to define the concrete class , its not a true Abstract Factory. But then again, we don't need to know either of these things, they are encapsulated within the implementation.
Factory Method
Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.
Since he is not defering instantiation to subclasses and instead defering them to instances, the OP is not doing a pure Factory Method either.
So in the end you could say that he is doing an amalgamation of all 3 patterns, as they are not really 100% mutually exclusive.
-stvn
I think maybe i need to switch to decaf :-P
| [reply] [Watch: Dir/Any] [d/l] [select] |