Php 一个类有多少个静态方法太多?
更新:重新表述这个问题,在这个类结构中,静态方法是否太多(我意识到现在只有4个,但我最初是从2开始的)?如果是这样的话,关于如何重构这些类以使用某种查找器类以便从模型类中删除静态函数,有什么建议吗 我有以下抽象类:Php 一个类有多少个静态方法太多?,php,oop,static,Php,Oop,Static,更新:重新表述这个问题,在这个类结构中,静态方法是否太多(我意识到现在只有4个,但我最初是从2开始的)?如果是这样的话,关于如何重构这些类以使用某种查找器类以便从模型类中删除静态函数,有什么建议吗 我有以下抽象类: abstract class LP_Model_Abstract { protected static $_collectionClass = 'LP_Model_Collection'; protected $_row = null; protected $_data = ar
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);
}
然后是这个类,它为类表继承方案提供了附加功能(其中类型对于以工厂方式确定附加功能很重要):
这些最终导致以下类型的类声明:
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;
}
}
什么时候知道一个类中有太多的静态方法?您将如何重构现有设计,使静态方法可能封装在某种查找器类中?在确定是否有许多静态方法时,我使用的第一个指标是方法功能是否无状态。如果静态方法改变了它们所在对象的状态,它们可能不应该是静态的。我必须同意Brubaker的观点,并补充到我的想法中,与其说是方法的数量,不如说是所述方法的功能。如果你开始认为你的类有很多方法(静态或其他),那么你可能会发现它们可以被重新分组并重构成一个更直观的体系结构。我会投入2美分 首先,我同意设置某种任意的限制是没有帮助的,比如“一旦我在一个太多的类中有超过10个静态!”。在有意义的时候重构,但不要仅仅因为达到了想象的边界就开始重构 我不会100%同意Brubaker关于有状态与无状态的评论——我认为问题更多的是类与实例。因为静态方法可以更改另一个静态属性的值,这是一个有状态更改
因此,可以这样想-如果方法/属性属于或属于类,那么它可能应该是静态的。如果该方法/属性属于或关于该类的实例,则它不应是静态的。我个人认为,任何数量的静态方法都是出现问题的迹象。如果您的类有实例方法和静态方法,那么很可能您可以将该类拆分为两个单独的实体,并将静态方法更改为实例方法
将类视为一种特殊的对象,其独特的特性是它本质上是全局的。因为它是一个全局变量,它意味着一个非常强的耦合级别,所以您希望减少对它的任何引用。静态成员需要被引用,这意味着您的代码将获得与类的强耦合。我同意BaileyP的观点,我将添加几分钱:
我一直认为一个班级应该有一个存在的理由;它应该有一项工作,而且应该做得很好。在确定了这一点,并弄清楚该类的接口应该是什么之后,我将遍历所有不会更改该类实例状态的函数,并将其标记为静态。如果您想构建可重用和可测试的代码,应该这样做。调用静态方法(或非数据类的构造函数)的代码不能单独测试
是的,如果消除静态方法,您将不得不传递更多的对象。这不一定是坏事。它迫使您以一种严谨的方式思考组件之间的边界和协作。让人想起了一个微软的笑话,从技术上讲是正确的,但在这种情况下并没有太大用处。主要是因为这些方法已经不修改对象的状态,它们只是返回对象或创建一个全新的对象。但无论如何,答案是thx很公平。我对php不太熟悉,因此在本例中没有太多的概念信息=(这也是一个很好的指标。我甚至没有考虑添加它,因为至少对我来说,这似乎是常识。@troelskn您将如何构造新类?我的想法是,静态方法是一种普遍的危险,而不是一种特定的危险,但应该尽可能地进行重构。如果我理解您的代码正确的话简而言之,只需将Artifact和ArtifactGateway视为两个完全独立的类。理论上,您可以有多个网关来处理同一实体(考虑非db存储或多个数据库)
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;
}
}