Statik Yöntemleri Kodu kokusunu çıkarmak için üstlenmeden

1 Cevap php

Ben oluşturmak gerekiyor her etki alanı nesnesi için geçerli temel yapıya sahiptir:

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

Ben başlangıçta sadece "bağlayıcı geç statik" php dünyada ne anlama geldiğini nihayet öğrenmek için ana LP_Model sınıfa statik yöntemler refactor çalıştı.

Herkes bu kod refactor nasıl bir öneriniz varsa ben oluşturmak her etki alanı nesnesi aynı üç fonksiyonu redeclare zorunda değilsiniz ki ben sadece merak ediyorum?

1 Cevap

Buna ne dersiniz:

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

?>

Ne yazık ki, aramak için fonksiyonları kolay hale getirmek için, her sınıfta get() ve getCollection() çoğaltmak zorunda. Diğer seçenek üst sınıfında işlevini çağırmak için:

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

Eğer bu yolu gitmek istiyorsanız temel sınıf ve fonksiyon isimleri yeniden adlandırabilirsiniz. Benim ilk örnekte olduğu gibi çocuk sınıfta bir klişe işlev yapmak, ya da başka benim ikinci örnekteki gibi bir dize sınıf adını ya: Ama nokta you must name the child class in one place or the other olmasıdır.