2008-12-24 36 views
4

我對每個域對象的當前基本結構,我需要創建:重構要刪除靜態方法代碼味道

class Model_Company extends LP_Model 
{ 
    protected static $_gatewayName = 'Model_Table_Company'; 
    protected static $_gateway; 
    protected static $_class; 

    public static function init() 
    { 
     if(self::$_gateway == null) 
     { 
      self::$_gateway = new self::$_gatewayName(); 
      self::$_class = get_class(); 
     } 
    } 

    public static function get() 
    { 
     self::init(); 

     $param = func_get_arg(0); 

     if($param instanceof Zend_Db_Table_Row_Abstract) 
     { 
      $row = $param; 
     } 
     elseif(is_numeric($param)) 
     { 
      $row = self::$_gateway->find($param)->current(); 
     } 

     return new self::$_class($row); 
    } 

    public static function getCollection() 
    { 
     self::init(); 

     $param = func_get_arg(0); 

     if($param instanceof Zend_Db_Table_Rowset_Abstract) 
     { 
      $rowset = $param; 
     } 
     elseif(!$param) 
     { 
      $rowset = self::$_gateway->fetchAll(); 
     } 

     $array = array();  

     foreach ($rowset as $row) 
     { 
      $array[] = new self::$_class($row); 
     } 

     return $array; 
    } 
} 

我最初試圖重構靜態方法到父LP_Model類只學習終於什麼是「後期靜態綁定」意味着在PHP世界。

我只是想知道如果任何人有如何重構這個代碼,這樣我就不必重新聲明中,我創建的每個域對象相同的三個功能建議?

回答

3

如何:

<?php 

abstract class Model_Abstract 
{ 
    protected $_gatewayName = null; 
    protected $_gateway = null; 

    protected function _init() 
    { 
     $this->_gateway = new $this->_gatewayName(); 
    } 

    protected function __construct($row = null) 
    { 
     $this->_init(); 
     if ($row) { 
      $this->_data = $row; 
     } 
    } 

    public static function getAbstract($class, $param) 
    { 
     $model = new $class(); 
     if($param instanceof Zend_Db_Table_Row_Abstract) 
     { 
       $row = $param; 
     } 
     elseif(is_numeric($param)) 
     { 
       $row = $model->_gateway->find($param)->current(); 
     } 

     return new $class($row); 
    } 

    public static function getAbstractCollection($class, $param = null) 
    { 
     $model = new $class(); 
     if($param instanceof Zend_Db_Table_Rowset_Abstract) 
     { 
       $rowset = $param; 
     } 
     elseif($param === null) 
     { 
       $rowset = $model->_gateway->fetchAll(); 
     } 

     $array = array(); 

     foreach ($rowset as $row) 
     { 
       $array[] = new $class($row); 
     } 

     return $array; 
    } 

    abstract public static function get($param); 
    abstract public static function getCollection($param = null); 
} 

class Model_Company extends Model_Abstract 
{ 
    protected $_gatewayName = 'Model_Table_Company'; 

    public static function get($param) { 
     return self::getAbstract(__CLASS__, $param); 
    } 

    public static function getCollection($param = null) { 
     return self::getAbstractCollection(__CLASS__, $param); 
    } 
} 

class Model_Table_Company extends Zend_Db_Table_Abstract 
{ 
    protected $_name = 'company'; 
} 

$model = Model_Company::get(1); 
print "Got an object of type ".get_class($model)."\n"; 

$models = Model_Company::getCollection(); 
print "Got ".count($models)." objects of type ".get_class($models[0])."\n"; 

?> 

不幸的是,使功能易於調用,你要複製get()getCollection()在每個子類。另一個選項是調用父類中的函數:

$model = Model_Abstract::getAbstract('Model_Company', 1); 
print "Got an object of type ".get_class($model)."\n"; 

$models = Model_Abstract::getAbstractCollection('Model_Company'); 
print "Got ".count($models)." objects of type ".get_class($models[0])."\n"; 

如果要轉到該路由,可以重命名基類及其函數名稱。但問題是,你必須在一個地方或其他名稱的子類:要麼使孩子類樣板功能在我的第一個例子,要不然名字符串類作爲我的第二個例子。

+0

再次感謝比爾。我知道你在前面的回答中提到了後期的靜態綁定,但是直到我開始重構代碼,才意識到這種限制的含義。看看你的第一個解決方案,它看起來很直觀。 – 2008-12-24 23:19:44