3

更新:在这个类结构中改写问题,“有太多”静态方法(我意识到现在只有 4 个,但我最初从 2 个开始)?如果是这样,关于如何重构这些类以使用某种 Finder 类以便我可以从模型类中删除静态函数的任何建议?

我有以下抽象类:

abstract class LP_Model_Abstract
{
protected static $_collectionClass = 'LP_Model_Collection';

protected $_row = null;

protected $_data = array();

public function __construct($row = null)
{
    $this->_row = $row;
}

public function __get($key)
{
    if(method_exists($this, '_get' . ucfirst($key)))
    {
        $method = '_get' . ucfirst($key);
        return $this->$method();            
    }
    elseif(isset($this->_row->$key))
    {
        return $this->_row->$key;
    }
    else
    {
        foreach($this->_data as $gateway)
        {
            if(isset($gateway->$key))
            {
                return $gateway->$key;
            }
        }
    }   
}

public function __set($key, $val)
{
    if(method_exists($this, '_set' . ucfirst($key)))
    {
        $method = '_set' . ucfirst($key);
        return $this->$method($val);            
    }
    elseif(isset($this->_row->$key))
    {
        $this->_row->$key = $val;
        return $this->_row->$key;
    }
    else
    {
        foreach($this->_data as $gateway)
        {
            if(isset($this->_data[$gateway]->$key))
            {
                $this->_data[$gateway]->$key = $val;
                return $this->_data[$gateway]->$key;
            }
        }
    }
}

public function __isset($key)
{
    return isset($this->_row->$key);
}

public function save()
{
    $this->_row->save();
}

abstract public static function get($params);
abstract public static function getCollection($params = null);
abstract public static function create($params);

}

然后这个类为类表继承方案提供额外的功能(其中类型对于以工厂方式确定额外功能很重要):

abstract class LP_Model_Factory_Abstract extends LP_Model_Abstract
{
    protected static $_collectionClass = 'LP_Model_Collection_Factory';

    abstract public static function factory($row);
}

这些最终导致以下类型的类声明:

class Model_Artifact extends LP_Model_Factory_Abstract
{
    protected static $_artifactGateway = 'Model_Table_Artifact';

    public static function create($params)
    {

    }

    public static function get($params) 
    {
        $gateway = new self::$_artifactGateway();

        $row = $gateway->fetchArtifact($params);

        return self::factory($row);        
    }

    public static function getCollection($params = null) 
    {
        $gateway = new self::$_artifactGateway();

        $rowset = $gateway->fetchArtifacts($params);

        $data = array(
            'data' => $rowset,
            'modelClass' => __CLASS__
        );

        return new self::$_collectionClass($data);
    }

    public static function factory($row)
    {
        $class = 'Model_Artifact_' . $row->fileType;
    }
}

你什么时候知道一个类中有太多的静态方法?您将如何重构现有设计,以便将静态方法封装在某种 Finder 类中?

4

6 回答 6

4

我必须同意 Brubaker 的观点,并在我的想法中补充一点,与其说是方法的数量,不如说是所述方法的功能。如果您开始认为您的类具有许多方法(静态或其他),那么您可能会发现它们可以重新分组并重构为更直观的架构。

于 2009-01-14T22:06:01.377 回答
3

在确定是否需要许多静态方法时,我使用的第一个指标是方法功能是否不是无状态的。如果静态方法改变了它们所在对象的状态,它们可能不应该是静态的。

于 2009-01-14T21:59:56.957 回答
2

我同意 BaileyP 的观点,我会加几分钱:

我一直认为一个类应该有一个存在的理由。它应该有一项工作,而且应该做得很好。在决定了这一点并弄清楚该类的接口应该是什么之后,我检查了所有不会更改类实例状态的函数并将其标记为静态。

于 2009-01-14T23:45:40.690 回答
2

如果你想构建可重用和可测试的代码,你应该完全避免使用静态方法。调用静态方法(或非类数据类的构造函数)的代码不能单独测试。

是的,如果您消除静态方法,您将不得不传递更多的对象。这不一定是坏事。它迫使您以规范的方式思考组件之间的边界和合作。

于 2009-01-15T02:10:05.813 回答
1

我会投入我的 2 美分。

首先,我同意设置某种任意限制是没有帮助的,例如“一旦我在一个类中有超过 10 个静态变量就太多了!”。在有意义的时候进行重构,但不要仅仅因为你已经达到了一些想象的边界就开始这样做。

我不会 100% 同意 Brubaker 关于有状态与无状态的评论——我认为问题更多是关于类与实例。因为静态方法可以更改另一个静态属性的值,这是一个有状态的更改。

所以,这样想——如果方法/属性属于或属于,那么它可能应该是静态的。如果方法/属性属于或属于类的实例,则它不应该是静态的。

于 2009-01-14T22:32:33.710 回答
1

就我个人而言,我发现任何数量的静态方法都是麻烦的迹象。如果您的类具有实例方法和静态方法,那么您很可能可以将类拆分为两个单独的实体并将静态方法更改为实例方法。

将类视为一种特殊的对象,具有其本质上是全局的独特属性。由于它是一个全局变量,它意味着非常强的耦合度,因此您需要减少对它的任何引用。需要引用静态成员,这意味着您的代码将获得与类的高度耦合。

于 2009-01-14T23:24:01.687 回答