Рефакторинг для удаления статических методов Код Запах

У меня есть текущая базовая структура для каждого объекта домена, который мне нужно создать:

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.

Мне просто интересно, есть ли у кого-нибудь предложения по тому, как реорганизовать этот код, чтобы мне не пришлось повторно использовать те же три функции в каждом объекте домена, который я создаю?

1 ответ

Как насчет этого:

<!--?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";

Вы можете переименовать базовый класс и его имена функций, если хотите пройти этот маршрут. Но дело в том, что вы должны назвать дочерний класс в одном месте или другом: либо сделать функцию шаблона в дочернем классе, как в моем первом примере, либо назвать класс в строке, как в мой второй пример.

licensed under cc by-sa 3.0 with attribution.