Jump to content


Photo

Registry pattern


  • Please log in to reply
8 replies to this topic

#1 redbullmarky

redbullmarky
  • Staff Alumni
  • Advanced Member
  • 2,863 posts
  • LocationBedfordshire, England

Posted 06 October 2006 - 11:58 AM

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
"you have to keep pissing in the wind to learn how to keep your shoes dry..."

I say old chap, that is rather amusing!

#2 Jenk

Jenk
  • Members
  • PipPipPip
  • Advanced Member
  • 778 posts

Posted 06 October 2006 - 12:09 PM

Singleton + Registry = Singleton Registry.

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

<?php

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

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

?>


#3 redbullmarky

redbullmarky
  • Staff Alumni
  • Advanced Member
  • 2,863 posts
  • LocationBedfordshire, England

Posted 06 October 2006 - 12:15 PM

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?
"you have to keep pissing in the wind to learn how to keep your shoes dry..."

I say old chap, that is rather amusing!

#4 Jenk

Jenk
  • Members
  • PipPipPip
  • Advanced Member
  • 778 posts

Posted 06 October 2006 - 12:17 PM

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.

#5 redbullmarky

redbullmarky
  • Staff Alumni
  • Advanced Member
  • 2,863 posts
  • LocationBedfordshire, England

Posted 06 October 2006 - 12:25 PM

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:

$this->obj =& get_instance();

"you have to keep pissing in the wind to learn how to keep your shoes dry..."

I say old chap, that is rather amusing!

#6 Jenk

Jenk
  • Members
  • PipPipPip
  • Advanced Member
  • 778 posts

Posted 06 October 2006 - 01:46 PM

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.

#7 redbullmarky

redbullmarky
  • Staff Alumni
  • Advanced Member
  • 2,863 posts
  • LocationBedfordshire, England

Posted 07 October 2006 - 09:38 AM

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).

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();
}

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?
"you have to keep pissing in the wind to learn how to keep your shoes dry..."

I say old chap, that is rather amusing!

#8 Jenk

Jenk
  • Members
  • PipPipPip
  • Advanced Member
  • 778 posts

Posted 07 October 2006 - 05:40 PM

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:

<?php

class A
{
    public static $instance;

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

        return self::$instance;
    }
}

?>

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

#9 redbullmarky

redbullmarky
  • Staff Alumni
  • Advanced Member
  • 2,863 posts
  • LocationBedfordshire, England

Posted 07 October 2006 - 05:56 PM

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.
"you have to keep pissing in the wind to learn how to keep your shoes dry..."

I say old chap, that is rather amusing!




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users