Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I have a few functions in PHP that read data from functions in a class

readUsername(int userId){
$reader = getReader();
return $reader->getname(userId);
}

readUserAddress(){
$reader = getReader();
return $reader->getaddress(userId);
}

All these make a call to

getReader()
{
require_once("Reader.php");
static $reader = new Reader();
return $reader;
}

An overview of Reader

class Reader{
getname(int id)
{
//if in-memory cache exists for this id return that
//else get from db and cache it
}

getaddress(int id)
{
 $this->getname(int id);
 //get address from name here
}

/*Other stuff*/

}

Why is class Reader needed The Reader class does some in-memory caching of user details. So, I need only one object of class Reader and it will cache the user details instead of making multiple db calls. I am using static so that it the object gets created only once. Is this the right approach or should I do something else?

share|improve this question
    
Why do you want to create the object only once (in the whole program; nothing wrong with a one-to-one object relationship)? –  delnan May 30 '12 at 19:12
    
Once the reader object is created it uses some in-memory caching. So if I call reader twice for getName and getAddress I will be doing many things twice. –  nischayn22 May 30 '12 at 19:15
    
Look up the Singleton design pattern. –  Gary Willoughby May 30 '12 at 19:16
    
I've taken a bit of a guess in my answer, but you've left out why Reader is even necessary. Does readUsername() just call $reader->getUsername(), and getUsername() always returns the same value, or is something more going on? –  Izkata May 31 '12 at 2:03
add comment

3 Answers

up vote -1 down vote accepted

static keywords, represents that, the class methods or attribute can be accessed without having any object instantiated. Due to this reason, they exists separately to maintain their loosely coupled state.

The problem you are having can be solved, with an combination of factory and singleton pattern.

Your Reader class should be singleton, so that multiplexed instances of same class of same purpose will not be created.

For example:

class Reader {
     private static $singletonObject = null;
     function __construct() { }

     public function static getInstance() {
        if(!SELF::$singletonObject) { SELF::$singletonObject = new Reader(); }
        return SELF::$singletonObject;
     }

     // Other
}

Now, whenever you are trying to access the Reader class,

$reader = Reader::getInstance();

Now, use $reader class as you need to. Now, you can create Factory and Singleton pattern to give you the instance of DB class and Cache Class.

share|improve this answer
add comment

Consider the Registry pattern, it provides a way of accessing global objects and avoids some drawbacks, that the Singleton has.

share|improve this answer
add comment

From your comment on the question:

Once the reader object is created it uses some in-memory caching. So if I call reader twice for getName and getAddress I will be doing many things twice.

Looks like Reader should be implemented roughly this way:

class Reader {
   private $name;
   public function getName() {
      if (isset($this->name)) { return $this->name; }

      $this->name = // Pull it from the database or wherever
      return $this->name;
   }
}

Usage is simple and straightforward, and getReader() probably isn't even necessary anymore:

require_once("Reader.php");
getReader()
{
   return new Reader();
}
share|improve this answer
    
how is getReader() not necessary? –  nischayn22 May 31 '12 at 2:35
    
@nischayn22 Well, look at the code there. The function is one single line. There isn't very much context for what getReader() is used for. –  Izkata May 31 '12 at 2:49
    
say I use new Reader() for getName, and then again for getAddress() then I will be creating two objects. But getAddress() could simply use the $this->name set by getName initially if I had one object. –  nischayn22 May 31 '12 at 3:06
    
@nischayn22 Are getAddress() and getName() global functions or class functions? –  Izkata May 31 '12 at 3:25
    
see my edit. Actually much more stuff is going on, so its difficult to explain no matter I tried my best –  nischayn22 May 31 '12 at 5:39
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.