Refactoring to remove static methods. Odor code

I have the current base structure for each domain object that I need to create:

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; } } 

First, I tried to reorganize the static methods into the parent class LP_Model, to finally find out what โ€œlate static bindingโ€ means in the php world.

I'm just wondering if anyone has any suggestions on how to reorganize this code so that I don't have to reuse the same three functions in every domain object that I create?

+4
source share
1 answer

How about this:

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

Unfortunately, to make functions convenient to call, you need to duplicate get() and getCollection() in each subclass. Another option is to call the function in the parent class:

 $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"; 

You can rename the base class and its function names if you want to go this route. But the fact is that you must name the child class in one place or another : either make the template function in the child class, as in my first example, or name the class in a string, as in my second example.

+3
source

All Articles