User Tools

Site Tools


php:factory

FACTORY PATTERN

The purpose of the factory pattern is to help you with loose coupling between different parts of a system. Instead of creating directly objects for your classes, we implement a central place who will return the new instances.

You'll understand easily this taking a look at the example below. We want to implement a Log system, with different behaviors for each type of log messages (error, notices, etc). First, the Log.class.php file what includes the interface, some classes based on that and the factory class (called Log):

Log.class.php

<?php
/*
 * Factory Pattern 
 * Log.class.php
 */
 
interface ILog {
    function saveLogMessage($msg);
    function echoLogMessage($msg);
}
 
/**
 * ERROR LOG
 * 
 */
class ErrorLog implements ILog {
    function echoLogMessage($msg) {
        echo "MESSAGE[ERROR]: $msg \n";
    }
 
    function saveLogMessage($msg) {
        // here save the error message to db for example
    }
}
 
/**
 * NOTICES LOG
 * 
 */
class NoticesLog implements ILog {
    function echoLogMessage($msg) {
        echo "MESSAGE[NOTICE]: $msg \n";
    }
 
    function saveLogMessage($msg) {
        // here save the notice message to db for example
    }
}
 
/**
 * FACTORY CLASS
 * 
 */
class Log {
    public static function factory($type) {
        try {
            $className = $type."Log";
            if (class_exists($className)) {
                return new $className;
            } else throw new Exception("Class $className doesn't exist");
        } catch (Exception $e) {
            echo $e->getMessage()."\n"; exit();
        }
    }
}

Then, in a separate index.php file, we call these:

index.php

require_once("Log.class.php");
 
$logob = Log::factory('Notices');
$logob->echoLogMessage("notice test message");
 
$logob = Log::factory('Error');
$logob->echoLogMessage("error test message");

The result is similar to:

$ php index.php 
MESSAGE[NOTICE]: notice test message 
MESSAGE[ERROR]: error test message 

php/factory.txt · Last modified: 2013/03/16 17:40 (external edit)