1

PHP单例模式与工厂模式比较

Posted by 撒得一地 on 2016年7月10日 in PHP笔记

简单来说,PHP单例模式就是一个功能用一个类来实现,并且在整个应用程序当中只有一个这个类的实例存在;

工厂模式强调的是面向对象的多态性,它可以把功能上的差异部分封装起来,对外实现共有的功能,比如说数据库的链接,由于数据库的不同,我们可能需要写不同的方法去实现数据库的链接,但作为应用程序来讲,它不需要了解数据库用的是MySQL还是Oracle,它只需要用query()这个方法去执行数据库的相应操作即可。这样就屏蔽了差异,使类更加健壮!

下面用书中的例子来具体看下:

单例模式:

class Database{
  private $_db;
  static $_instance;

  private function __construct(){
     $this->_db = pg_connect('dbname = example_db');
  }

  private __clone() {};

  public static function getInstance(){
   if(!(self::$_instance instanceof self)){
     self::$_instance = new self();
   }
   return self::$_instance;
  }

  public function query($sql){
   return pg_query($this->_db,$sql);
  }   

由于构造函数和克隆方法都被私有化,即外部不能通过new()来实现类的调用,这样就保证了在应用程序中不可能有多个实例存在。在 getInstance()方法中,首先判断该类是否已经被实例化,如果没有实例化,则进行实例化并保存类的实例到_instance变量中。     

使用单例类:

$db = Database::getInstance();

$db = query("SELECT * FROM table");

单例模式优点:1.节省系统资源;2.单例模式在维持应用程序状态的同步方面尤其有用。

工厂模式:

interface IImage{
   function getHeight();
   function getWidth();
   function getData();
}
class Image_PNG implements IImage{
  private $_width,$_height,$_data;

  public function __construct($file){
    $this->_file = $file;
    $this->_parse();    
  }

  private function _parse(){
    //获取PNG的参数并填充到$_width,$_height,$_data中
  }

  public function getWidth(){
     return $this->_width;
  }

  public function getHeight(){
    return $this->_height;
  }

  public function getData(){
   return $this->_data;
  }
}

class Image_JPEG implements IImage{
  private $_width,$_height,$_data;

  public function __construct($file){
    $this->_file = $file;
    $this->_parse();    
  }

  private function _parse(){
    //获取jpeg的参数并填充到$_width,$_height,$_data中
  }

  public function getWidth(){
   return $this->_width;
  }

  public function getHeight(){
   return $this->_height;
  }

  public function getData(){
   return $this->_data;
  }
}
class ImageFactory{
  public static function factory($file){
  $pathParts = pathinfo($file);

  switch(stotolower($pathParts['extension'])){
      case 'jpg':
      $ret = new Image_JPEG($file);
      break;

      case 'png':
      $ret = new Image_PNG($file);
      break;
      default:
      //error message  
  }

  if($ret instanceof IImage){
     return $ret;
  }else{
     //erro message
  } 
 }
}

在IImage接口中,我们定义了公共的方法,具体的实现交给它的继承者。可以看到,在imageFactory这个"工厂"中并没有具体的功能实现,它屏蔽了具体的功能细节部分,它做的只是差异的判断,然后根据这个差异来调用相应的类来完成工作。

使用工厂实例:

$image = ImageFactory::factory('/path/test.png');
echo $image->getWidth();

工厂模式优点:1.方便类的调用者,使其不用去关注差异部分(如果没有工厂模式,则调用者必须在调用类之前去做类型判断,然后决定去调用哪个类);2. 方便扩展,如果继续添加新的类型,只需要添加新的工厂方法即可,不需要修改调用者的主程序(如果没有工厂模式,则需修改主程序的判断部分然后决定调用相应的类)。

原文:http://zhwlsoft.blog.163.com/blog/static/176371202201182732134113/

上一篇:

下一篇:

相关推荐

1 Comment

Comments are closed. Would you like to contact the author directly?
网站地图|XML地图

Copyright © 2015-2024 技术拉近你我! All rights reserved.
闽ICP备15015576号-1 版权所有©psz.