Page 1 of 1

Dynamic factory pattern

Posted: Wed Apr 01, 2009 6:35 pm
by hccoelho
Hi

I'm a newbie in PHP language, although i'm very familiar with java and OO languages. I already check that php don't support var typing and class cast, that is very strange for me, for exempl i'm used to have interfaces and cast it implementation to that interface, e.g.

JAVA:

public interface animal { ... }
public dog implements animal { ... }

Animal a = new Dog();

However i didn't find a way to do this in PHP, in my case i want to do a dynamic factory class:

So i've defined the following user class:

Code: Select all

 
abstract class User{
    // The parameterized factory method
    public static function getInstance()
    {
        if (include_once $implementation_class.'.php') {
            //get the classname from configuration constant
           $implementation_class = “business/UserImplementation”;
            $classname = substr($implementation_class,strrpos($implementation_class, "/")+1, strlen($implementation_class));
            return new $classname;
        } else {
            throw new Exception ('The class ' .$implementation_class . ' was not found in configuration file.');
        }
        
    }
 
    abstract getUserName();
    abstract getEmail();
...
}
 

And after I’ve defined the UserImplementation in other folder (business) that extends User and implement all abstract methods.

But I want to cast the new class to User in order to getInstance method give me User classes. I want to do something like the highlighted code:

Code: Select all

 
abstract class User{
    // The parameterized factory method
    public static function getInstance()
    {
        if (include_once $implementation_class.'.php') {
            //get the classname from configuration constant
           $implementation_class = “business/UserImplementation”;
            $classname = substr($implementation_class,strrpos($implementation_class, "/")+1, strlen($implementation_class));
            return new (User) $classname;
        } else {
            throw new Exception ('The class ' .$implementation_class . ' was not found in configuration file.');
        }
        
    }
 
    abstract getUserName();
    abstract getEmail();
...
}
 
So when I do User::getInstance() I’m really get User object and not UserImplementation object.

Do you have any idea that could help me on this? How can i do dynamic factoring in php separating the specification layer from business layer, getting this layers completely independent between them?

Thanks in advance.

Chris Corbyn | Please wrap your PHP code inside

Code: Select all

 and [/ php][/b] tags when posting on the forum[/color]

Re: Dynamic factory pattern

Posted: Thu Apr 02, 2009 2:40 pm
by Christopher
My quick guess as to why this code is not working is because in PHP you reference properties with $this->implementation_class.

Re: Dynamic factory pattern

Posted: Thu Apr 02, 2009 6:40 pm
by hccoelho
Can you be more specific?

Re: Dynamic factory pattern

Posted: Thu Apr 02, 2009 7:16 pm
by Christopher
You are using a bunch of uninitialized variables in your methods. I am guessing that you are used to Java where properties are not prefixed. In PHP you access properties with $this->. So $this->implementation_class is a class property, whereas $implementation_class is a local variable.

Re: Dynamic factory pattern

Posted: Thu Apr 02, 2009 9:16 pm
by Chris Corbyn
And if the class variable is static, you access it with self:: or parent::

Code: Select all

class SuperClass {
  const SOME_CONSTANT = 42; //Like Java's final public static ... 
  public static $varName = 'value';
}
 
class SubClass extends SuperClass {
  public $property = 'thing';
  public static $varName = 'other';
  public function showVar() {
    echo self::$varName;
  }
  public function showSuperclassVar() {
    echo parent::$varName;
  }
  public function showConstant() {
    echo self::SOME_CONSTANT;
  }
  public function showProperty() {
    echo $this->property;
  }
}
 
$o = new SubClass();
$o->showVar(); //other
$o->showSuperclassVar(); //value
$o->showConstant(); //42
$o->showProperty(); //thing
 
echo $o->property; //thing
 
echo SuperClass::SOME_CONSTANT; //42
echo SubClass::SOME_CONSTANT; //42
 
echo SuperClass::$varName; //value
echo SubClass::$varName; //other
 
You have to be explicit about the object in the which the member can be found.

Java uses just "this" and "super". PHP can be confusing to get your head around. It uses $this in object scope, "self" in static scope, "parent" in both static and object scope if you need to refer to the superclass.