##Singleton
The single pattern is an often used pattern in many applications when only a single instance of a resource is required. The most obvious type of resource for PHP web pages is a database connection, although other resource types can be used. When fetching of dynamically creating a web page several database calls may need to be made. If a single instance of the resource could be used, rather than creating several connections, the overhead is minimized. The single instance in this case, is created by the singleton pattern.
<?php
class db {
/*** Declare instance ***/
private static $instance = NULL;
/**
* the constructor is set to private so
* so nobody can create a new instance using new
*/
private function __construct() {
/*** maybe set the db name here later ***/
}
/**
* Return DB instance or create intitial connection
* @return object (PDO)
* @access public
*/
public static function getInstance() {
if (!self::$instance) {
self::$instance = new PDO("mysql:host='localhost';dbname='animals'", 'username', 'password');
self::$instance->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
return self::$instance;
}
/**
* Like the constructor, we make __clone private
* so nobody can clone the instance
*/
private function __clone() {
}
} /*** end of class ***/
?>
Lets look at what has happened in the singleton class above. A variable name `$instance` is created and made `private`, this ensures nobody and try to access it directly. Similarly, the constructor and __clone methods have been made private to prevent cloning of the class, or of somebody trying to instantiate an instance of it. The class has a single method for providing a resource, the `getInstance()` method.
The `getInstance()` method checks that an instance does not already exist. If no instance exists a new instance of the PDO class is created and assigned to the `$instance` variable. If an existing instance is available, the `getInstance()` method returns this. The result is that the returned value is always the same instance, and no new resource, or overhead, is required.
Here is a small demonstration of how this might be used in an application.
<?php
try {
/*** query the database ***/
$result = DB::getInstance()->query("SELECT animal_type, animal_name FROM animals");
/*** loop over the results ***/
foreach ($result as $row) {
print $row['animal_type'] .' - '. $row['animal_name'] . '<br />';
}
} catch (PDOException $e) {
echo $e->getMessage();
}
?>
##Factory
The factory pattern is a class that creates objects for you, rather than you needing to use the new keyword to create one yourself. The factory is, as the name suggests, a factory for creating objects. Why do we need this? Lets consider an application that uses an `ini` file for configuration option. Then the application is changed to gain the configuration options from a database. The rest of the application falls apart like a house of cards as the base is removed.
This “*tight coupling*” of objects, where each object relies heavily on another, creates problems in larger applications. A system is needed where objects can reference each other, but are not inter dependent.
In our example of the configuration file becoming a database, if other classes were dependent on the class that read from the `ini` file, and this was suddenly tasked to the database class problems occur.
By using the factory design pattern, if you change the type of object from the `ini` reader class to the database class you only need to change the factory. Any other code that uses the factory will be updated automatically.
<?php
/**
* @config interface
*/
interface Config {
function getName();
}
/**
* @config class
*/
class userConfig implements Config {
/*
* @username
*/
public $user_id;
/*** contructor is empty ***/
public function __construct($id) {
$this->user_id = $id;
}
public static function Load($id) {
return new userConfig($id);
}
public function getName() {
try {
/*** query the database ***/
$sql = "SELECT username FROM user_table WHERE user_id=:user_id";
$db = db::getInstance();
$stmt = $db->prepare($sql)
$stmt->bindParam(':user_id', $this->user_id, PDO::PARAM_INT);
return $stmt->fetch(PDO::FETCH_COLUMN);
} catch (PDOException $e) {
/*** handle exception here ***/
return false;
}
}
} /*** end of class ***/
/*** returns instance of config ***/
$conf = userConfig::Load( 1 );
echo $conf->getName();
?>
This might seem a little excessive code for simply retrieving a username. But in large-scale application where a change from file based to database retrieval is made, the results could be catastrophic. Here its is simply a matter of changing the the `getName()` method retrieves the name, and the returned object is the same, thus allowing other parts of the application that require the username, eg: a login for a cart, to continue as they did previously.