SitePoint Sponsor

User Tag List

Page 1 of 2 12 LastLast
Results 1 to 25 of 36
  1. #1
    SitePoint Wizard dreamscape's Avatar
    Join Date
    Aug 2005
    Posts
    1,080
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Multipleton Pattern (maybe?)

    Ok, so I'm not entirely sure if "Multipleton" is the right term to use. A google search turned up very little other than a few C++ pages.

    Anyways, a Singleton not only always returns the current instance, but it also only allows a single instance in the program, right. However, sometimes we need something similar to a Singleton, but need to invoke more than one instance in a program, usually not many, but still more than one.

    For a few parts of my app I am building, I needed something that would always return the current instance, but would also allow multiple instances throughout the program (only 1 instance at any given time though). For example, I need this in the template system, which usually invokes 2 instances during execution (think of it as a 2-pass engine). Up till now I had been just using a global var, the same var for each instance, so that whenever I used it, it would always use the current instance.

    But just now in a blur of insight, I've come up with a pattern to solve this problem without using global vars. Note, this is written for PHP4, and since only functions can have static vars, it took a bit of thinking and tricks to implement... It is no doubt a million times easier to implement in PHP5 since the class itself can have a static var, and probably requires far less thinking.

    I have probably overlooked something silly, so I post here for peer review, enjoyment, use, or whatever you may or may not like to do with it, including mercilessly tearing it apart:
    PHP Code:
    <?php
    /**
     * Multipleton for PHP 4
     * 
     * Allow multiple instances of a class,
     * but only one at a time,
     * and always return the current (last) instance upon request
     */
    class Multipleton {

        function 
    Multipleton($param1$param2$param3) {
            
    $this->setCurrentInstance($this);
        }

        function &
    getCurrentInstance() {
            
    $object NULL;

            return 
    Multipleton::setCurrentInstance($objectfalse);
        }

        function &
    setCurrentInstance(&$object$set_instance true) {
            static 
    $instance = array();

            if (
    $set_instance === true) {
                
    $instance[0] = &$object;
            }

            if (
    sizeof($instance) > 0) {
                return 
    $instance[0];
            }
        }

    }


    /**
     * example, creating first instance
     */
    $multipleton = &new Multipleton($param1$param2$param3);


    /**
     * example, getting the current instance
     */
    $multipleton = &Multipleton::getCurrentInstance();


    /**
     * example, creating second instance
     */
    $multipleton = &new Multipleton($param4$param5$param6);

    /**
     * example, getting the current instance
     */
    $multipleton = &Multipleton::getCurrentInstance();

    ?>
    Last edited by dreamscape; Aug 21, 2005 at 14:14.

  2. #2
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I think the Registry pattern would solve your needs.
    http://www.phppatterns.com/index.php...leview/75/1/1/

  3. #3
    SitePoint Wizard dreamscape's Avatar
    Join Date
    Aug 2005
    Posts
    1,080
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    >> I think the Registry pattern would solve your needs.

    and I think I've already solved the problem, and my method does it just as well.

    *edit* what I mean is, while a repository/registry may be useful for many global objects, it seems like a waste to make one to just wrap a single object in.
    Last edited by dreamscape; Aug 19, 2005 at 10:45.

  4. #4
    SitePoint Wizard DougBTX's Avatar
    Join Date
    Nov 2001
    Location
    Bath, UK
    Posts
    2,498
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    It sounds like the Factory pattern. The code for the class would look much the same but externally you would have:

    PHP Code:
    // creating first instance 
    $multipleton = &Multipleton::createNewInstance($param1$param2$param3); 

    // returns first instance
    $multipleton = &Multipleton::getCurrentInstance(); 

    // creating second instance 
    $multipleton = &Multipleton::createNewInstance($param4$param5$param6); 

    // returns second instance
    $multipleton = &Multipleton::getCurrentInstance(); 
    Also, I'd use Multipleton::new() and Multipleton::current() instead for succinctness.

    Regards,
    Douglas
    Hello World

  5. #5
    SitePoint Addict
    Join Date
    May 2005
    Posts
    255
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Generally speaking, any instance where this could be useful would be solved by just having a normal class with a few static properties / methods. Typically it's far easier to program as well.

  6. #6
    SitePoint Wizard dreamscape's Avatar
    Join Date
    Aug 2005
    Posts
    1,080
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    >> Generally speaking, any instance where this could be useful would be solved by just having a normal class with a few static properties / methods

    Isn't that exactly what I have done? The Multipleton isn't meant to be a container or wrapper to other classes, but something you design in a normal class, similar to a Singleton, except it allows more than one instance throughout the program (but still only one at a time). The pattern as posted is just that, a conceptual pattern. Not a real world example.

    What you suggest is exactly what the Multipleton does... uses a static property and a few methods in a normal class.

    As is, it is written for PHP 4, because PHP 4 does not have static class properties. It only has static method properties, and so one must do some trickery to simulate a static class variable, either by doing something like I've done, or using a global variable seem to be the 2 most common methods.

    However, PHP 5 does have static class properties, which is why I said doing the same thing in PHP 5 would require much less thinking and coding.

    Again, the Multipleton is not designed to be an object wrapper of any kind, but something to be integrated to a normal class. It is meant as an answer to where one needs a Singleton, but needs to re-initiate at some point in the program, which is not allowed by a true Singleton, therefore becoming a "Multipleton"

    Where you need multiple objects, then something like the Registry is probably much better suited than having multiple Multipletons.

  7. #7
    SitePoint Addict
    Join Date
    May 2003
    Location
    The Netherlands
    Posts
    391
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Maybe I'm overlooking something, but wouldn't be the following easier?
    PHP Code:
    /**
    * Multipleton for PHP 4
    *
    * Allow multiple instances of a class,
    * but only one at a time,
    * and always return the current (last) instance upon request
    */
    class Multipleton {

        function &
    Multipleton() {
        }

        function 
    Init($param1$param2$param3){
        }

        function &
    GetInstance(){
            static 
    $instance = array();

            if (isset(
    $instance[0])!==TRUE){
              
    $instance[0]=&new Multipleton();
            }
            return 
    $instance[0];
        }
    }


    /**
    * example, creating first instance
    */
    $multipleton = &Multipleton:GetInstance();
    $multipleton -> Init($param1$param2$param3);

    /**
    * example, creating second instance
    */
    $multipleton = &Multipleton:GetInstance();
    $multipleton -> Init($param4$param5$param6); 
    There’s more than one way to skin a cat.

  8. #8
    SitePoint Wizard dreamscape's Avatar
    Join Date
    Aug 2005
    Posts
    1,080
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I think you've answered your own question with your signature, no?

  9. #9
    SitePoint Addict
    Join Date
    May 2003
    Location
    The Netherlands
    Posts
    391
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by dreamscape
    I think you've answered your own question with your signature, no?
    Well, it isn't there for nothing ...

    Even though, the question still remained. I didn't know for sure if that was what you were trying to achieve.
    There’s more than one way to skin a cat.

  10. #10
    SitePoint Wizard dreamscape's Avatar
    Join Date
    Aug 2005
    Posts
    1,080
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by nacho
    Even though, the question still remained. I didn't know for sure if that was what you were trying to achieve.
    Actually no, yours doesn't quite do what I'm doing. I am allowing new instances to be initiated, but always have the class return the current instance of itself. With your example, it is really a Singleton, because it will only allow the class to be initiated once. You then seems to simulating a new instance with the Init() method, or so I guess that is what one would use that method for. If you code your class to simulate a new initiation in an Init() method, then yes it will effectively do the same thing, but ultimately require more coding... ok, I know only one line more each time you need a "new" instance (I am quoting "new" because it is not really a new instance).

    I prefer to just have the class handle it, and every time you call a new instance, have the constructor set itself as the current instance, and every time you make a call to get the instance, the current instance is returned.

    Indeed my code for doing this in PHP4 is quite ugly to say the least, but only because no static class properties exist in PHP4. However, if one were to conceptually translate to PHP5 what I've put forth, it would be a quite easy and simple coding for a class that may need it.
    Last edited by dreamscape; Aug 21, 2005 at 23:33.

  11. #11
    SitePoint Addict
    Join Date
    May 2003
    Location
    The Netherlands
    Posts
    391
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by dreamscape
    I prefer to just have the class handle it, and every time you call a new instance, have the constructor set itself as the current instance, and every time you make a call to get the instance, the current instance is returned.
    Of course, I won't discuss your own preferences, do it like you like it most, but I fail to see what you're doing so differently. Could you maybe explain what is your need to be calling a constructor time after time? What's the benefit for you against just initializing the object (through an own method) with different parameters?
    There’s more than one way to skin a cat.

  12. #12
    SitePoint Wizard dreamscape's Avatar
    Join Date
    Aug 2005
    Posts
    1,080
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    >> but I fail to see what you're doing so differently

    I'm not doing much differently than your example. Again, your signature is the answer to your puzzlement here. I'm beginning to wonder if you even believe what you've put as a signature The only real difference between our methods is that 1) I allow more than once instance, and you limit it to 1, and 2) I use the constructor to re-initialize and re-set the instance where you use a custom method Init() to re-initialize the class.

    >> Could you maybe explain what is your need to be calling a constructor time after time?

    It's not being called time after time... or should not be. The Multipleton as I see it should only be used when you have a single class that you need to re-initialize a couple times (3 would be the limit IMO). Anything else, another pattern would be better (like a registry for multiple classes and objects).

    In my case, I created it for a dual pass template engine. Pass 1 compiles the specific page's template. Pass 2 compiles the overall main layout's template, and merges the two. Each pass needs a new instance of the template engine class. Throughout the code, template variables may be set in a few different places, namely in what I have dubbed the "page controller" (though if you're a Java zealot you might call it something else), in service plugins, and in a special area that sets template variables that are available to either pass of the engine. Now then, I created this "Multipleton" so that in each of these areas, one can get the current instance of the template engine object, whether it be pass 1 or pass 2.

    I used the constructor to set the current instance, because it contains everything necessary for the class to function as a "Multipleton" within the class itself.

    I didn't say it was the only way, nor did I say it was the best way. There are no "best ways," only ways that better adapt to the situation at hand.

  13. #13
    SitePoint Addict
    Join Date
    May 2003
    Location
    The Netherlands
    Posts
    391
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by dreamscape
    I'm beginning to wonder if you even believe what you've put as a signature
    I do blindly but the fact that there is more than one way to achieve things does not mean AT ALL that I always happen to know which one is correct. PIP, I-am-human, PIP

    Anyway, I still don't see very well where you're hitting at so I'll be back.

    (Have to leave now).
    There’s more than one way to skin a cat.

  14. #14
    SitePoint Wizard dreamscape's Avatar
    Join Date
    Aug 2005
    Posts
    1,080
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    >> I do blindly but the fact that there is more than one way to achieve things does not mean AT ALL that I always happen to know which one is correct.

    Bingo... There is no such thing as the "correct way"

    All the solutions and suggestions put forth in here can be "correct"

    Philosophically speaking, "correct" has no basis in reality and is just a notion created by the mind... oh wait this is the a PHP forum. Guess I better keep philosophy in my pocket when I'm in here

  15. #15
    SitePoint Wizard DougBTX's Avatar
    Join Date
    Nov 2001
    Location
    Bath, UK
    Posts
    2,498
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by nacho
    Maybe I'm overlooking something, but wouldn't be the following easier?
    Imagine:

    PHP Code:
    /**
    * example, creating first instance
    */
    $alpha = &Multipleton:GetInstance();
    $alpha -> Init($param1$param2$param3);

    /**
    * example, creating second instance
    */
    $beta = &Multipleton:GetInstance();
    $beta -> Init($param4$param5$param6); 
    compared to:

    PHP Code:
    #   first instance 
    $alpha =& Multipleton::new($param1$param2$param3);
    $alpha =& Multipleton::current(); 

    #   second instance 
    $beta =& Multipleton::new($param4$param5$param6);
    $beta =& Multipleton::current(); 
    Obviously the second one is sexier. Oh, no, that wasn't what I was talking about...

    In the first case, $alpha == $beta, in the second case, $alpha != $beta.

    Which one is broken?

    If you've got documentation, take a look at that. If you write the documentation, whichever one you like, just keep them both up-to-date. but, if you just like to pretend you write the documentation...

    Doulgas
    Hello World

  16. #16
    SitePoint Addict
    Join Date
    May 2003
    Location
    The Netherlands
    Posts
    391
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I meant correct as being a solution to the problem. I understood your problem as having to populate an object with initial values several times (initializing), not as having two different objects (instances). I did not question that your own solution works, but I wanted to point out that it might be another solution that also suited the problem, which you didn't think about before (that's also the meaning of my sig - not that I would have the solution, but that it could very well be one we did not think about).

    Right or wrong are, as you well say, philosophical, but that does not imply that a solution might not be better suited to fit a problem than any other. It's well known that there are many ways to get to Rome, but we both certainly agree that it is shorter to go straight to Rome from Amsterdam, than going through Sidney. (I didn't say better, but shorter).

    Quote Originally Posted by dreamscape
    In my case, I created it for a dual pass template engine. Pass 1 compiles the specific page's template. Pass 2 compiles the overall main layout's template, and merges the two. Each pass needs a new instance of the template engine class.
    If I understand it now, you actually want two different objects because they perform different tasks, so I'd say, make two different classes, MarkupTemplate and StyleTemplate and use a generic Template class to merge both. You could even use the generic Template class as a Façade to MarkupTemplate and StyleTemplate, so you don't need to construct the specific templates yourself, but through a method of the generic Template class (e.g. myTemplate->AddToMarkupTemplate()).

    Quote Originally Posted by DougBTX
    Which one is broken?
    Don't really see where you're getting at, but I'd say none. They're just different solutions to different problems. Or you meant my typo (it should read &Multipleton::GetInstance())?

    Quote Originally Posted by DougBTX
    If you've got documentation, take a look at that. If you write the documentation, whichever one you like, just keep them both up-to-date. but, if you just like to pretend you write the documentation...
    I don't have the slightest clue what you're talking about.
    There’s more than one way to skin a cat.

  17. #17
    SitePoint Wizard DougBTX's Avatar
    Join Date
    Nov 2001
    Location
    Bath, UK
    Posts
    2,498
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by nacho
    Don't really see where you're getting at, but I'd say none. They're just different solutions to different problems. Or you meant my typo (it should read &Multipleton::GetInstance())?
    I was referring to another thread, probably not the most transparent way to go about it

    I think I was just pointing out the main difference between the two setups. With the "re-init" version you reset every instance )because there is only one instance...), but with the "new/current" setup, any instances you already have stay as they are.

    Douglas
    Hello World

  18. #18
    SitePoint Addict
    Join Date
    May 2003
    Location
    The Netherlands
    Posts
    391
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I had the feeling it had something to do with the thread Only variables should be assigned by reference, but I couldn't place it for sure ...

    Coffee?
    There’s more than one way to skin a cat.

  19. #19
    SitePoint Guru Galo's Avatar
    Join Date
    May 2005
    Location
    Holland!
    Posts
    852
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Multipleton how long did that take you to choose as the name

    The power behind the singleton has IMHO nothing todo with multiple singletons, and why would you use multiple singletons if we have the registry pattern... ?

    dont try and re-invent the weel

    cheers
    Business as usual is off the menu folks, ...

  20. #20
    SitePoint Wizard dreamscape's Avatar
    Join Date
    Aug 2005
    Posts
    1,080
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    >> The power behind the singleton has IMHO nothing todo with multiple singletons

    No sherlock homes

    >> and why would you use multiple singletons if we have the registry pattern...

    Who here has said anything about using this for multiple singletons? Several times in here I have explicitly said, that if one needed multiple objects, that there are better options, like the registry.

    But I thank you for blatantly not reading the entire thread, and instead just reading a few sentences and posting a hastily reply. Your ability to completely ignore the obvious and act rashly is a champion of human kind. Perhaps I should nominate you for the nobel prize
    Last edited by Helge; Aug 23, 2005 at 02:13. Reason: Removed swearing

  21. #21
    SitePoint Addict
    Join Date
    May 2005
    Posts
    255
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by dreamscape
    >> Generally speaking, any instance where this could be useful would be solved by just having a normal class with a few static properties / methods

    Isn't that exactly what I have done? The Multipleton isn't meant to be a container or wrapper to other classes, but something you design in a normal class, similar to a Singleton, except it allows more than one instance throughout the program (but still only one at a time). The pattern as posted is just that, a conceptual pattern. Not a real world example.

    What you suggest is exactly what the Multipleton does... uses a static property and a few methods in a normal class.

    As is, it is written for PHP 4, because PHP 4 does not have static class properties. It only has static method properties, and so one must do some trickery to simulate a static class variable, either by doing something like I've done, or using a global variable seem to be the 2 most common methods.

    However, PHP 5 does have static class properties, which is why I said doing the same thing in PHP 5 would require much less thinking and coding.

    Again, the Multipleton is not designed to be an object wrapper of any kind, but something to be integrated to a normal class. It is meant as an answer to where one needs a Singleton, but needs to re-initiate at some point in the program, which is not allowed by a true Singleton, therefore becoming a "Multipleton"

    Where you need multiple objects, then something like the Registry is probably much better suited than having multiple Multipletons.
    I think you're missing my point. You're trying to invent a design pattern when the basic language constructs already do this -- it's the way you're supposed to design. Not every piece of code you ever write needs to use esoteric CS garbage, you know.

  22. #22
    SitePoint Wizard dreamscape's Avatar
    Join Date
    Aug 2005
    Posts
    1,080
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    >> I think you're missing my point. You're trying to invent a design pattern when the basic language constructs already do this -- it's the way you're supposed to design.

    No you miss the point. PHP 4 does not have basic language constructs to do this. If you can't come off your PHP 5 high horse, kindly leave the thread alone.

  23. #23
    SitePoint Wizard
    Join Date
    Oct 2001
    Posts
    2,686
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    There is no need to attacking each other. Discuss in a civilized manner and this thread won't be closed. This is the only warning you people get.

  24. #24
    SitePoint Addict
    Join Date
    Jan 2005
    Location
    Ireland
    Posts
    349
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Would a term more like Writable Singleton make more sense than Multipleton. It isn't holding multiple instance, but rather you can change the instance the singleton is holding and discard the old one (in other words, the Singleton is no longer read-only).

    A Registry simply makes more sense to me, though I know you have dimissed it.

  25. #25
    SitePoint Guru OfficeOfTheLaw's Avatar
    Join Date
    Apr 2004
    Location
    Quincy
    Posts
    636
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Sorry, I read the thread, but don't really get what you are meaning to do that isn't done by the registry pattern. I'm not attacking your implementation or anything, after all you should create the objects in your system to suit your needs, not someone elses idea of what a pattern should be.. but why not use a registry to store multiple instances of objects to get? It's hackish in php4, but doable.

    I'll avoid the actual class code, but the idea would be to have a static array variable contained in a method that is called privatly, with a parameter specifying whether to get or store objects, and another optional parameter to pass objects in on store. This would be called internally, externally you can use set and get methods that call that method to store and retrieve instances.

    Further, you could even store some kind of reference to the most recently added instance, which you could access via Registery::getCurrentInstance();

    Code:
    Registry::store('foo1', new Foo());
    Registry::store('foo2', new Foo());
    
    /** 
     * get an instance to work with
     */
    $foo = &Registry::getInstance('foo1');
    Of course, like I stated, software design is something that is done to often cater the application of the code, and for all I know your method works betetr in YOUR case and in your application rather than a registry does. I think all the hostility is that people don't feel this is a pattern because, quite honestly, it borders between a Singleton and a Registry (mostly a registry). Remember, patterns aren't concrete and could be implemented in a multitude of ways... I have some old application code that uses a simple function as a registry and, although you won't find any code examples in pattern theory literature that even slightly resembles the function, it does do what a registry is described to do.

    James Carr, Software Engineer


    assertEquals(newXPJob, you.ask(officeOfTheLaw));


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •