I\'m new to design patterns and I cant really see a difference between this two patterns, both are creational patterns arent they? and what is the purpose of each pattern? t
The singleton 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 or 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.
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.
query("SELECT animal_type, animal_name FROM animals");
/*** loop over the results ***/
foreach ($result as $row) {
print $row['animal_type'] .' - '. $row['animal_name'] . '
';
}
} catch (PDOException $e) {
echo $e->getMessage();
}
?>
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.
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.