Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Re: how do you call this? $x->bar();

by rinceWind (Monsignor)
on Mar 15, 2004 at 14:55 UTC ( [id://336712]=note: print w/replies, xml ) Need Help??


in reply to how do you call this? $x->bar();

So, in a nutshell, your objects of class "Thing" contain the class name of the back end class, in the hash member $x->{backend}. As far as I am concerned, this is perfectly acceptable.

There may be alternatives, if for instance you actually need to have (and keep track of) an object blessed into the back end class, associated with the "Thing" object. In this case, you would just store a reference to this object (you can then get its class name using ref if you really want it).

Another alternative is the factory pattern, where method calls in your "Thing" class spit out backend objects given parameters, etc.

It's a case of TIMTOWDI.

--
I'm Not Just Another Perl Hacker

Replies are listed 'Best First'.
Re: Re: how do you call this? $x->bar();
by stvn (Monsignor) on Mar 15, 2004 at 15:59 UTC

    Another alternative is the factory pattern, where method calls in your "Thing" class spit out backend objects given parameters, etc.
    It seems to me that a factory pattern is exactly what he is doing here.
    package main; my $x = Thing->new( backend => 'A' ); $x->backend->do();
    Of course the way he is doing it is not the way the Gang of Four show in the Design Patterns book, but he's not coding it in C++ or smalltalk (which they do).

    Much as you say, TIMTOWTDI.

    -stvn
      It seems to me that a factory pattern is exactly what he is doing here.

      Not to quibble, but no, I don't think that's what "factory pattern" means.

      A factory hides the mechanics of constructing new objects behind another interface, whereas all of the instantiation done in this example is explicit.

      I'd say the OP is showing a behavior composition technique, like the GoF's Strategy pattern, expressed in proper Perl idiom.

        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

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://336712]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (4)
As of 2024-04-16 06:38 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found