views:

553

answers:

2

I am working with PHP classes and objects now. In this question the names of fields and methods are made up just so you get an idea of what I am talking about.

It is related to using the singleton and registry design patterns.

Now lets say I need to access a Database object, Cache Object, Core Settings object, Session object in almost every other class I will need to have access to these. SO I would use a registry to store all 4 of those object into 1 registry class object. I could then easiyl just pass in my 1 object into any other object that needs to access these. So that sounds great so far but what if I have some classes that do not need all 4 of those objects, what If I ONLY need to access the Database object or the Session object in some of my other classes? For perfromance would it be best to just use a singleton inside these other objects or would it be the same to go ahead and use my registry in these?

I do not know well enough how the objects work in PHP to know if there would be any sort of performnce gain (less memory usage, cpu usage, load time).

So anyone with experience in this maybe can tell me if there would be any gain using one or the other, I am at the stage where I can go ether way without it affecting production time or anything. I would like to use the best method if I can now.

+4  A: 

You can implement lazy loading to only load the objects you really need:

class Registry
{
    private static $database = null;

    private static function connectDatabase($key)
    {
        [... do connection stuff ...]
    }

    public static function getDatabase($key)
    {
        if (Registry::$database == null)
        {
            Registry::connectDatabase($key);
        }
        return Registry::$database;
    }
}

The code to register the database connection parameters is left as exercise to the reader.

dbemerlin
Isn't this just a singleton?
jasondavis
+1  A: 

That depends on your application. If you still need 3 out of the 4 classes, then it'd be more ideal to use the Registry than to handle the 3 independently only because you don't need the fourth. Loading the classes lazily would be one approach to reduce memory footprint, but then you need to instruct the registry when to create the objects and that's not much different than handling singletons. Alternatively, you could create an n-parameter constructor or use an array to instruct your Registry which classes to instantiate during construction.

class Registry {
    public $class1;
    public $class2;

    function __construct($uses) {
        foreach($uses as $class) {
            $this->{$class} = new {$class}();
        }
    }

}

Then instantiate your Registry by specifying which classes to instantiate.

$reg = new Registry(array('class1'));

You would obviously want your constructor to handle zero parameters to account for instantiating all classes by default.

bkuhns
Thats a cool idea, thanks. I should mention, even if 1 class only needs 1-2 of the objects, there is already another class being called on the same page most likely that will also have all 4 objects already injected into it. I am not sure how the memory stuff weorks though so it may be already loaded 1 time. I don't know if the memory would store the objects more then once in ram or not.
jasondavis
My code example assumes your classes hold onto their own instance of your Registry. This would mean lots of excess memory if you have more than one class per page utilizing the same common Registry objects. If you're using a static/global instance, then your implementation would be different than my example but it could still be done. This would also mean sharing the same objects in memory across all classes, which would be much more efficient.To get my example to work that way, make a Registry::initInstances() function instead of using the constructor.
bkuhns
Ok thats what I was thinking, guess we are on the same page, kind of like the method from dbemerlin below.
jasondavis