Skip to content

Brilliant Coding Blog

Be Brilliant

Refactoring to Factory Function in PHP

Tags:
Posted on: Last modified: Published by: Matthew Jackowski

This is a quick example to show a simple PHP refactoring for object creation.  Specifically our goal is to use static functions to better encapsulate our object constructor calls.

In this example, we assume that we have a flexible message constructor that allows us to build messages given some text and time information.


public function __construct( $text, $scheduleTime, $waitDuration ) {
	if ( $scheduleTime ) {
	        $this->sendTime = $scheduleTime;
	} else if ( $waitDuration ) {
		$this->sendTime = time() + $waitDuration;
	} else {
		$this->sendTime = time();
	}
	$this->text = $text;
}

A very direct way of creating message objects is to simply invoke the ‘new’ keyword to assign new messages to variables, like this:


$msg1 = new Message( 'say anything', false, false );
$msg2 = new Message( 'say anything later', '2012-05-21 22:02:00', false );
$msg3 = new Message( 'wait a  bit to say anything', false, 20 );

The reason we want to refactor this approach is because when you directly call the constructors, you need to ensure that all of the params are given, even if there are some params which can be omitted for a given message ‘type’. So instead, it would be easier to simply specify the params we need for the 3 message ‘types’. So let’s introduce a class and some static functions to help us with this encapsulation:


class MessageFactory {
	static function immediateMessage( $text ) {
		return new Message( $text, false, false );
	}

	static function scheduledMessage( $text, $time ) {
		return new Message( $text, $time, false );
	}

	static function delayedMessage( $text, $duration ) {
		return new Message( $text, false, $duration );
	}
}

Now creating our messages is much easier:


$msg1 = MessageFactory::immediateMessage( 'say anything' );
$msg2 = MessageFactory::scheduledMessage( 'say anything later', '2012-05-21 22:02:00' );
$msg3 = MessageFactory::delayedMessage( 'wait a  bit to say anything', 20 );

Even though the factory functions adds a few extra lines of code, it is worthwhile because it clarifies the intent during object creation.  Also it provides a useful buffer between the object classes and our code such that if the object constructor change, we can manage these changes directly in the factory functions.

It’s also important to note that the full factory method pattern involves much more complexity and will require subclasses or interfaces.  Wikipedia has an example of this type of approach in PHP here.
The full version of this code can be found in a Gist here.

Refactoring to Factory Function in PHP