2008-12-24 37 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