单身人士与工厂模式的区别

我是新来的devise模式,我真的不能看出这两种模式之间的差异,两者都不是他们的创作模式? 每种模式的目的是什么? 谢谢。

单例模式可以确保你总是找回你正在检索的types相同的实例,而工厂模式通常会给你一个不同types的实例。

单例的目的是让所有的调用都通过同一个实例。 一个例子可能是一个pipe理磁盘caching的类,或者从静态字典中获取数据; 无论哪里重要,只有一个已知的实例与资源进行交互。 这确实使其不易扩展。

工厂的目的是创build并返回新的实例。 通常,这些实际上不会是相同的types,但它们将是相同基类的实现。 但是,每种types都可能有很多例子

独生子

单个模式是许多应用程序中经常使用的模式,只需要一个资源的单个实例。 PHP网页最明显的资源types是数据库连接,尽pipe可以使用其他资源types。 在获取dynamic创build网页时,可能需要进行多次数据库调用。 如果可以使用资源的单个实例,而不是创build多个连接,则开销被最小化。 这种情况下的单个实例是由单例模式创build的。

<?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 ***/ ?> 

让我们看看在上面的单例类中发生了什么。 一个variables名$instance被创build并且被private ,这确保没有人并且直接访问它。 类似地,构造函数和__clone方法已经被私有化,以防止克隆类,或者有人试图实例化它的一个实例。 该类有一个提供资源的方法,即getInstance()方法。

getInstance()方法检查一个实例是否已经存在。 如果没有实例存在,则创buildPDO类的新实例并将其分配给$instancevariables。 如果现有的实例可用,则getInstance()方法将返回此实例。 结果是返回的值总是相同的实例,并且不需要新的资源或开销。

这是一个小应用程序如何使用它的示例。

 <?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(); } ?> 

工厂模式是为您创build对象的类,而不是您自己需要使用新的关键字创build对象。 顾名思义,工厂就是创build物体的工厂。 我们为什么需要这个? 让我们考虑一个使用ini文件作为configuration选项的应用程序。 然后,应用程序被更改为从数据库获取configuration选项。 随着底座被移除,应用程序的其余部分就像一幢房子一样分崩离析。 对象的“ 紧密耦合 ”(每个对象严重依赖另一个对象)会在较大的应用程序中产生问题。 一个系统需要对象可以相互引用,但不相互依赖。
在我们的configuration文件成为一个数据库的例子中,如果其他类依赖于从ini文件读取的类,并且这突然被分派到数据库类,则会发生问题。
通过使用工厂devise模式,如果将对象types从ini阅读器类更改为数据库类,则只需更改工厂。 任何其他使用该工厂的代码将被自动更新。

 <?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(); ?> 

这似乎有点过分的代码只是检索一个用户名。 但是,在从文件检索到数据库检索的大规模应用中,结果可能是灾难性的。 这里只是简单的改变getName()方法检索名称,而返回的对象是相同的,因此允许需要用户名的应用程序的其他部分(例如:购物车的login名)继续以前做过。

Singleton模式确保只有一个类的实例存在,并且通常提供一个众所周知的即全局的访问点。

Factory模式定义了创build对象的接口(不限制多less个接口),并且通常抽象控制要实例化哪个类。

单例模式是一种模式,其目的是确保无论客户端(或多个客户端)要求为其创build(实例化)这个特定types的实例多less次,它们将始终得到完全相同的一个一种types的实例。 它保证只有一个types的实例可以被实例化(例如,如果Type正在pipe理某个数据结构的内存caching副本中的200 MByte – 你只想要一个副本)Singletontypes通常会有一个工厂方法,向提出请求的客户提供一个且只有一个实例。

Factory方法是一种封装types的创build或实例化的方法,以便types本身可以控制实例化的方式。

Singleton始终返回相同的类实例,工厂可以通过实例化各种类或使用其他分配scheme (如对象池)来创build对象。 所以单身人士可以在工厂模式中使用