Difference between singleton and factory pattern
I'm new to design patterns and I can开发者_StackOverflowt really see a difference between this two patterns, both are creational patterns arent they? and what is the purpose of each pattern? thanks.
A singleton pattern ensures that you always get back the same instance of whatever type you are retrieving, whereas the factory pattern generally gives you a different instance of each type.
The purpose of the singleton is where you want all calls to go through the same instance. An example of this might be a class that manages a disk cache, or gets data from a static dictionary; wherever it is important only one known instance interacts with the resource. This does make it less scalable.
The purpose of the factory is to create and return new instances. Often, these won't actually be the same type at all, but they will be implementations of the same base class. However, there may be many instances of each type
Singleton
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.
<?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.
Singleton | Factory |
---|---|
Returns Same instance | Returns various new instances |
Single Constructor hiding | Multiple Constructors expose |
No interface | Interface driven |
No Subclasses | Subclasses |
The Singleton pattern ensures that only one instance of the class exists and typically provides a well-known, i.e., global point for accessing it.
The Factory pattern defines an interface for creating objects (no limitation on how many) and usually abstracts the control of which class to instantiate.
Singleton pattern is a pattern whose purpose is to ensure that no matter how many times a client (or multiple clients) ask for an instance of this specific Type to be created (instantiated) for them, they will always get the exact same one and only one instance of the type. It guarantees that only one instance of the type can ever be instantiated (like for instance if the Type is managing a 200 MByte in memory cached copy of some data structure - you only want one copy to exist) A Singleton Type will generally have a factory method in it, to deliver to requesting clients that one and only one instance.
A Factory method is a method that encapsulates the creation or instantiation of a type so that the type itself has control over how it is instantiarted.
Singleton returns the same instance of class all the time, factory can create objects by instantiating various classes, or by using other allocation schemes such as an object pool. so singleton can be used in factory pattern
精彩评论