문제

작성해야 할 각 도메인 객체의 현재 기본 구조가 있습니다.

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 세계에서 "늦은 정적 바인딩"이 무엇을 의미하는지 최종적으로 배우기 위해 노력했습니다.

내가 만든 모든 도메인 객체에서 동일한 세 가지 함수를 재개 할 필요가 없도록이 코드를 리팩터링하는 방법에 대한 제안이 있는지 궁금합니다.

도움이 되었습니까?

해결책

이건 어때:

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

해당 경로로 이동하려면 기본 클래스 및 기능 이름의 이름을 바꿀 수 있습니다. 그러나 요점은 그 것입니다 한 곳이나 다른 곳에서 자식 수업을 지정해야합니다.: 첫 번째 예제에서와 같이 아동 클래스에서 보일러 플레이트 기능을 만들거나 두 번째 예에서와 같이 문자열의 클래스를 이름으로 지정하십시오.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top