Jump to content

Archived

This topic is now archived and is closed to further replies.

redbullmarky

Registry pattern

Recommended Posts

right then, hopefully i can explain this properly...

i'm in the process of sorting out all my old scripts that i use over and over into a nice tidy framework. not just as a practical exercise but a learning one too.

i've been looking through the code of the Code Igniter framework (http://www.codeigniter.com) and out of all the ones i've looked at so far, this is the most comfortable one to understand and probably what i'll base much of my own on.

now the code uses what i can only describe as a registry (in system/library/codeigniter/common.php for anyone following along), only its not a registry class but a procedural registry instead.

after reading about the registry pattern on phppatterns, they state that you pass the registry alone by parameter to classes that need it. however, Code Igniter uses a function called 'get_instance' which appears to do do this job.

so onto my question. i do prefer this way of doing it - ie, using a function instead of passing it as a parameter. i've made a registry class, and also a function to return an instance of the registry. apart from "OOP best practice", is there anything seriously wrong with what i'm doing or any pitfalls i may find later down the line?

Cheers
Mark

Share this post


Link to post
Share on other sites
Singleton + Registry = Singleton Registry.

The static method get_instance() will be the Singleton, the rest will be the Registry.

[code]<?php

$reg = Registry::getInstance(); // user Singleton to retrive Registry instance.

$reg->assign('foo', $bar); // user Registry.

?>[/code]

Share this post


Link to post
Share on other sites
ok lovely. just so i understand better, can you think of any reason why they would use a function to do it instead of a straightforward Registry::getInstance() call?

Share this post


Link to post
Share on other sites
functions are naturally on the global scope, and perhaps the developers are "lazy" and don't want to type Registry::get_instance() everytime they need access to the registry, so only need to type get_instance(); instead.

Makes no real difference but I'd atleast user a more descriptive name, personally. It's also not very OO to use functions like that.

Share this post


Link to post
Share on other sites
hmm makes sense.

would it be fair to say though that if i was to use a function, it would be easier if (for some reason, being awkward) i changed the name of my registry class? here's an example of a line found in the constructor of a class that uses the registry in Code Igniter:

[code]$this->obj =& get_instance();[/code]

Share this post


Link to post
Share on other sites
Singleton's are not looked upon brightly in the OO world, infact some more so than function calls.

The reason why is just the same, should the name change of the Singleton entity (be it the function, or the class) then there is potentially huge amounts of refactoring to be done.

The 'true' OO practice is to pass the registry around as a parameter, as mentioned by phppatterns. This doesn't have to be a constructor parameter, it can be a setter.

Share this post


Link to post
Share on other sites
hmm ok makes sense. i guess i'm looking at a few different ways and seeing which i'm more comfortable with. one thing you maybe able to help me get my head around though, as it's the only thing i cant. the line i posted previously, get_instance, doesnt seem to be getting the registry at all (still talking about CodeIgniter here). each controller (for example welcome.php) extends a class called Controller, which then extends a class called CI_Base. _load_class is a function that enters an object into a registry. The CI_Base class and get_instance are in the same file (Base5.php).

[code]
class CI_Base {
  public function CI_Base()
  {
      $instance =& _load_class('Instance');
      $instance->set_instance($this);
  }
}

class Instance {
  public static $instance;

  public function set_instance(&$object)
  {
      self::$instance =& $object;
  }
 
  public function &get_instance()
  {
      return self::$instance;
  }
}

function &get_instance()
{
  $instance =& _load_class('Instance');
  return $instance->get_instance();
}
[/code]

now - in the Controller class (which extends the CI_Base), it uses the 'get_instance' function call. from what I can follow, it seems to be trying to get an instance of the entire object, from the base downwards. But if Controller extends Base, surely Controller has access to Base and its descendents anyway? What would you say is the purpose of structuring it like this?

Share this post


Link to post
Share on other sites
Sounds to me like they have it confused.. I barely touched OO in php4, becuase it was that bad, but in php5 this is all that's needed to implement a singleton pattern:

[code]<?php

class A
{
    public static $instance;

    public static function getInstance()
    {
        if (is_null(self::$instance)) self::$instance = new A;

        return self::$instance;
    }
}

?>[/code]

If you extend a singleton class (not wise to do so) then you'll just have to overload the method getInstance()

Share this post


Link to post
Share on other sites
fair does. it was written for PHP4 although some bits are there to take advantage of 5, so maybe that could be a reason...
what i'm trying to work out is the best structure for my framework, and CI is so far the easiest to understand (apart from the above point) and well organised.
the way i've thought about it is to have an object registry (singleton or function used to retrieve it from other classes). my individual modules extend the controller which extends my core. a core method, "loadLibrary" actually allows me to load classes (like template engine, db handling, etc) on the fly - like a plugin architecture, and these are available in my modules by: $this->$libraryname (eg, $this->template->draw, $this->db->query). the entire thing is kept in the registry and retrieved with Registry::Load('Core'), so that classes that arent descendents of the main structure can use the main structures bits and pieces.

That probably didnt make a hell of a lot of sense, and it's possibly fair to say that i'm stepping out of my (current) depth right now, but if you grasp what i'm doing above, then by all means point out if i'm doing something terribly wrong.

Share this post


Link to post
Share on other sites

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.