The best time to use Factory Pattern?

Okay it says.
Factory pattern says it will create object for you.
An example of factory pattern codes,


<?php
interface IUser
{
  function getName();
}

class User implements IUser
{
  public static function Load( $id )
  {
        return new User( $id );
  }

  public static function Create( )
  {
        return new User( null );
  }

  public function __construct( $id ) { }

  public function getName()
  {
    return "Jack";
  }
}

$uo = User::Load( 1 );
echo( $uo->getName()."\
" );
?>

So when is the best time to use Factory Pattern.
And can you guys give sample scenario.

Thank you very much in advanced.

Firstly, using static methods as factories is self defeating.

One of the reasons for using factories is polymorphism. As soon as you call “User::load()” that flexibility is lost. If you replace that with " $factory->load() " then you have added flexibility, because $factory can be an instance of anything, not necessarily an instance of the User class. Also, grouping the object creation and the object implementation is a poor separation of concerns. A better method is this:




class UserFactory {
	public function load($id) {
		return new User($id);
	}
}


class User implements IUser {
	public function getName() {
		return $this->name;
	}
}



$uo = $factory->load(1);

This way, the code using the factory isn’t tightly coupled to the factory itself, $factory can be an instance of anything.

When should you use the factory? If you’re using the factory method you’d use the factory everywhere you’d normally call “new User”.

This is because it keeps all object initialisation logic in one place. Imagine this:


if ($_SESSION['Admin'] == true) return new AdminUser($id);
else return new User($id);

If that logic changes, say we add a “ModeratorUser” type, then the logic only needs to be updated in the factory. Everywhere that’s creating users will remain unchanged and just call $factory->load($id);

I’m using factory() in my ORM models all the time so I can chain methods in one line, e.g. $users = User::factory()->where(‘column’, ‘value’)->limit(5)->get();

Without it I would always need to use at least 2 lines:

$users = new User();
$users->where('column', 'value')->limit(5)->get();

A point can be made that static creation methods can be used in place of the new keyword( by making the constructor private ) to allow greater clarity on creation. Basically named constructors.

eg.

(more in depth http://www.informit.com/articles/article.aspx?p=1398606 )
http://c2.com/cgi/wiki?FactoryMethodPattern
http://c2.com/cgi/wiki?CreationMethod

Php is slight different as it does not have overloading but named constructors can help by removing the need for default values be part of public api and confer what the construction means. Say for a response from a service instead of a boolean and a requirement to call other accessor to get the error out( quite boring to test and far less useful to return further back through the call chain ).


<?php

class Response {
    /**
     * @var bool
     */
    private $isSuccessful;

    /**
     * @var string
     */
    private $errorMessage;


    /**
     * @param boolean $isSuccessful
     * @param string  $errorMessage
     */
    private function __construct( $isSuccessful, $errorMessage ) {
        $this->isSuccessful = $isSuccessful;
        $this->errorMessage = $errorMessage;
    }


    /**
     * @return Response
     */
    public static function createSuccess() {
        return new self( true, '' );
    }


    /**
     * @param string $errorMessage
     *
     * @return Response
     */
    public static function createError( $errorMessage ) {
        return new self( false, $errorMessage );
    }


    /**
     * @return boolean
     */
    public function getIsSuccessful() {
        return $this->isSuccessful;
    }


    /**
     * @return string
     */
    public function getErrorMessage() {
        return $this->errorMessage;
    }
}

Or to allow the use of classes as constant values that can be passed safely at run time which have a guaranteed limited prevalidated set of values so do not need continual revalidating through the next steps in the call chain. eg.


class BloodGroup{
    /**
     * @var string
     */
    private $bloodGroup;


    private function __construct( $bloodGroup ) {
        $this->bloodGroup = $bloodGroup;
    }

    public static function A(){
        return new self('A');
    }


    public static function B(){
        return new self('B');
    }


    public static function O(){
        return new self('O');
    }


    public static function AB(){
        return new self('AB');
    }


    /**
     * @param int $type -- comes from database
     *
     * @throws Exception
     * @return \\BloodGroup
     */
    public static function createFromType( $type ) {
        switch( $type ){
            case 1:
                return self::A();

            case 2:
                return self::B();

            case 3:
                return self::O();

            case 4:
                return self::AB();
        }

        throw new Exception( 'type ' . $type . 'is an unrecognised type' );
    }


    function __toString() {
        return $this->bloodGroup;
    }
}

This example draws paralells to
http://sourcemaking.com/refactoring/replace-type-code-with-class and sometimes a later refactoring moves to replace type code with subclasses if further behaviour is required across the values. These may look similar to usual factories but it is a technique to remove primitives and allow small pieces of self validating behaviour to be put in their place.

These techniques are not used very often as they are quite small but can prove very useful as they are for the direct replacement of the new keyword. The first for clarity when an order of parameters means something in human terms, the second for flexibility in future refactoring and also the safety as it can be type hinted and trusted to behave accordingly without further checks from outside wherever it is passed.

Sometimes factory method and creation method are used interchangeably which can obscure it.

Tom is right that that factories are far more useful when injectable than static due to the mocking it allows and interchangeability using polymorhpism ). These examples are usually asserted against as a result from a method call.

eg.


$this->assertEquals( Response::createError('problem'), $testClass->testCall('failing value');