Magento单例模式的实现与使用

来源:互联网 发布:网络大电影成本 编辑:程序博客网 时间:2024/06/05 21:42

单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。这个类称为单例类。
单例模式的要点有三个;一是某个类只能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例。
一个典型的php单例模式实现如下:

<?php  Class Catalog{      /**      * Description:私有化构造函数,防止外界实例化对象      */      private static function __construct()      {      }      /**      * Description:私有化克隆函数,防止外界克隆对象      */      private function __clone()      {      }       //静态变量保存全局实例    static private $_instance=NULL;      private $product;              //get single object      public function getInstance(){          if( is_null( self::$_instance ) || !isset(self::$_instance) ){             self::$_instance=new Catalog();          }          return self::$_instance;      }      public function setProduct($product) {        $this->product = $product;    }      public function getProduct($product) {        $this->product = $product . PHP_EOL;    } }  $product1 = Catalog::getInstance();$product1->setProduct('shirt');$product1->getProduct();$product2 = Catalog::getInstance();$product2->setProduct('sweater');$product2->getProduct();$product1->getProduct();?>result:jacky  vivian  vivian

以上的就是PHP中的单例模式,PHP中的单例模式是有缺点的:对于某个类,如果有时候我需要的是单个实例,有时候需要的是不同的实例,这时候单例模式就是个障碍了。而在Magento中,由于Class Mage 是作用在整个request 过程,基于Mage的特点,Mage提供了两个static方法:getModel()和getSingleton()
getModel():每次获取的是是不同的实例

getSingleton():每次获取的是是同一的实例
详细的代码如下:

   /**     * Retrieve model object     *     * @link    Mage_Core_Model_Config::getModelInstance     * @param   string $modelClass     * @param   array $arguments     * @return  Mage_Core_Model_Abstract     */     public static function getModel($modelClass = '', $arguments = array())     {         return self::getConfig()->getModelInstance($modelClass, $arguments);     }     /**     * Retrieve model object singleton     *     * @param   string $modelClass     * @param   array $arguments     * @return  Mage_Core_Model_Abstract     */     public static function getSingleton($modelClass='', array $arguments=array())     {         $registryKey = '_singleton/'.$modelClass;      //检测当前的对象是否已经存在,如果存在则取出来         if (!self::registry($registryKey)) {      //self::getModel的用途是实例化对象,然后把对象通过self::register()保存,             self::register($registryKey, self::getModel($modelClass, $arguments));         }         return self::registry($registryKey);     }  

下面我就分别举个例子:

1、单例模式:getSingleton()

$product1 = Mage::getSingleton('catalog/product');$product1->setProductName('shirt');echo $product1->getProductName();$product2 = Mage::getSingleton('catalog/product');$product2->setProductName('sweater');echo $product2->getProductName();echo $product1->getProductName();result:shirt  sweater  sweater

2、getModel

$product1 = Mage::getModel('catalog/product');$product1->setProductName('shirt');echo $product1->getProductName();$product2 = Mage::getModel('catalog/product');$product2->setProductName('sweater');echo $product2->getProductName();echo $product1->getProductName();result:shirt sweater shirt

所以在一次请求过程中,每次使用Mage::getModel(‘XXX’) 获得的都是不同的object,每次使用Mage::getSingleton(‘XXX’) 获得的都是同一的object
(作者自理解)单例模式是php设计模式中的一个经典设计模式,是一种代码思想,用好了对减少资源的消耗,减少服务器的压力是很有帮助的。回到单例模式,我理解的就是getModel就是两个或多个同样的一元钱硬币,我分别把他们分给不同的人让他们去花,那么最后每个人花完剩下的钱就是归到每个人的身上,这里的一块钱就是相同类别的类,而最后每个人剩下的就是代码中使用之后得到的不同的结果。
而getSingleton就是我给几个人一块钱让他们去花,那么他们怎么花都是在这一块钱上也就是代码中都是作用在同一个类上的。
单例模式的思想同样可以使用在方法上,例如:同一个商品多次访问一个方法的时候这样是很消耗资源的,这时候使用单例模式的思想对减轻资源的消耗是有极大的帮助的。举例如下:

private $thirdCategoryId = null;/** * Retrieve product category id * * @return mixed */public function getThirdCategoryId(){    if (is_null($this->thirdCategoryId)) {        $categoryIds = $this->getCategoryIds();        $categoryCollection  = Mage::getModel('catalog/category')->getCollection()            ->addAttributeToSelect('name')            ->addAttributeToSelect('is_active')            ->addAttributeToSelect('category_type')            ->addAttributeToFilter('category_type', array('eq'=>0))            ->addAttributeToFilter('is_active', array('eq'=>1))            ->addAttributeToFilter('level', array('eq'=>4))            ->addAttributeToFilter('entity_id', array('in'=>$categoryIds))->getFirstItem();        if($categoryCollection->getId()){            $this->thirdCategoryId = $categoryCollection->getId();        }else{            $categoryCollection  = Mage::getModel('catalog/category')->getCollection()                ->addAttributeToSelect('name')                ->addAttributeToSelect('is_active')                ->addAttributeToSelect('category_type')                ->addAttributeToFilter('category_type', array('eq'=>0))                ->addAttributeToFilter('is_active', array('eq'=>1))                ->addAttributeToFilter('level', array('eq'=>3))                ->addAttributeToFilter('entity_id', array('in'=>$categoryIds))->getFirstItem();            $this->thirdCategoryId = $categoryCollection->getId()?: '';        }    }    return $this->thirdCategoryId;}

这里就是当一个商品要多次调用这个方法的时候就会做出判断,如果$this->thirdCategoryId为空的时候就会执行这个方法,而当$this->thirdCategoryId不为空的时候就直接返回这个值。

原创粉丝点击