更新:重新提出问题,'这个类结构中是否有太多'静态方法(我意识到现在只有4个,但我最初只有2个)?如果是这样,有关如何重构这些类以使用某种Finder类的任何建议,以便我可以从Model类中删除静态函数吗?
我有以下抽象类:
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类中?
答案 0 :(得分:4)
我不得不同意Brubaker,并补充一点,我认为这不是方法的数量,而是所述方法的功能。如果你开始认为你的类有许多方法(静态或其他方法),那么你可能会发现它们可以重新分组并重构为更直观的架构。
答案 1 :(得分:3)
我在确定是否需要许多静态方法时使用的第一个指标是方法功能是否为无状态。如果静态方法改变了它们所在对象的状态,它们可能不应该是静态的。
答案 2 :(得分:2)
我同意BaileyP,我会添加几个便士:
我总是认为一个班级应该有一个存在的理由;它应该有一个工作,它应该做得很好。在确定并确定该类的接口应该是什么之后,我会通过标记任何不会将类实例的状态更改为静态的函数。
答案 3 :(得分:2)
如果要构建可重用且可测试的代码,则应avoid static methods altogether。调用静态方法(或非类数据类的构造函数)的代码无法单独测试。
是的,如果消除静态方法,则必须传递更多对象。这不一定是坏事。它迫使您以纪律的方式思考组件之间的界限和合作。
答案 4 :(得分:1)
我会投入2美分。
首先,我同意设置一些任意限制是没有用的,例如“一旦我在一个太多的类中有超过10个静态!”。当它有意义时重构,但不要因为你遇到一些想象的边界而开始这样做。
我不会100%同意Brubaker关于有状态与无状态的评论 - 我认为问题更多的是关于类与实例。因为静态方法可以更改另一个静态属性的值,这是一个有状态的更改。
所以,想想这样 - 如果方法/属性属于或属于类,那么它应该是静态的。如果方法/属性属于或属于该类的实例,则它不应该是静态的。
答案 5 :(得分:1)
我个人发现任何数量的静态方法都是麻烦的表现。如果您的类具有实例方法和静态方法,则很可能您可以将该类拆分为两个单独的实体,并将静态方法更改为实例方法。
将一个类视为一种特殊的对象,具有独特的属性,它本质上是全局的。由于它是一个全局变量,它意味着非常强的耦合级别,因此您希望减少对它的任何引用。需要引用静态成员,这意味着您的代码将与类强烈耦合。