UPDATE: Rephrasing the question to ask, 'are there too many' static methods (I realize that right now there are only 4 but I originally started with 2) in this class structure? If so, any suggestions on how to refactor these classes to use some sort of Finder class so that I can remove the static functions from the Model classes?
更新:重新提出问题,'有太多'静态方法(我意识到现在只有4个,但我最初只有2个)在这个类结构中?如果是这样,有关如何重构这些类以使用某种Finder类的任何建议,以便我可以从Model类中删除静态函数?
I have the following abstract class:
我有以下抽象类:
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);
}
And then this class which provides additional functionality for class table inheritance schemes (where type is important in determining additional functionality in a factory fashion):
然后这个类为类表继承方案提供了额外的功能(其中类型对于以工厂方式确定附加功能很重要):
abstract class LP_Model_Factory_Abstract extends LP_Model_Abstract
{
protected static $_collectionClass = 'LP_Model_Collection_Factory';
abstract public static function factory($row);
}
These ultimately result in the following type of class declaration:
这些最终会导致以下类型的类声明:
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;
}
}
When do you know that you have too many static methods in a class? And how would you refactor the existing design so that the static methods are perhaps encapsulated in some sort of Finder class?
你什么时候知道你的类中有太多的静态方法?您将如何重构现有设计,以便静态方法可能封装在某种Finder类中?
6 个解决方案
#1
Personally I find that any number of static methods are a sign of trouble. If your class has instance methods and static methods, then most likely you could split the class into two separate entities and change the static methods to instance methods.
就个人而言,我发现任何数量的静态方法都是麻烦的表现。如果您的类具有实例方法和静态方法,则很可能您可以将该类拆分为两个单独的实体,并将静态方法更改为实例方法。
Think of a class as a special kind of object, with the distinctive property that it is global by nature. Since it's a global variable, it implies a very strong level of coupling, so you would want to reduce any references to it. Static members will need to be referred, meaning that your code will get a strong level of coupling to the class.
将一个阶级视为一种特殊的对象,具有独特的属性,它本质上是全球性的。由于它是一个全局变量,它意味着非常强的耦合级别,因此您希望减少对它的任何引用。需要引用静态成员,这意味着您的代码将获得与类的强大耦合程度。
#2
I'd have to agree with Brubaker and add that to my thinking it isn't the number of methods so much as the functionality of said methods. If you start thinking that your class has to many methods (static or otherwise) then you might find they can be re-grouped and refactored into a more intuitive architecture.
我不得不同意Brubaker的意见,并补充一点,我认为这不是方法的数量,而是所述方法的功能。如果您开始认为您的类有许多方法(静态或其他方法),那么您可能会发现它们可以重新分组并重构为更直观的体系结构。
#3
The first indicator I use when determining if I have to many static methods is if the methods functionality is not stateless. If the static methods change the state of the object they reside in, they probably shouldn't be static.
我在确定是否需要许多静态方法时使用的第一个指标是方法功能是否为无状态。如果静态方法改变了它们所在对象的状态,它们可能不应该是静态的。
#4
I agree with BaileyP and I'll add my couple of pennies:
我同意BaileyP,我会加上几个便士:
I always work with the idea that a class should have a single reason for existing; it should have one job that it does, and it should do it well. After deciding that, and figuring out what the interface to that class should be, I go through and mark any functions that don't change the state of an instance of the class as static.
我总是认为一个班级应该有一个存在的理由;它应该有一份工作,它应该做得很好。在确定并确定该类的接口应该是什么之后,我会通过并标记任何不会将类实例的状态更改为静态的函数。
#5
If you want to build reusable and testable code, you should avoid static methods altogether. Code which calls static methods (or constructors of non-data-like classes) cannot be tested in isolation.
如果要构建可重用且可测试的代码,则应完全避免使用静态方法。调用静态方法(或非类数据类的构造函数)的代码无法单独测试。
Yes, you will have to pass around alot more objects if you eliminate static methods. This is not necessarily a bad thing. It forces you to think about the boundaries and cooperation between your components in a disciplined way.
是的,如果你消除静态方法,你将不得不传递更多的对象。这不一定是坏事。它迫使您以纪律的方式思考组件之间的界限和合作。
#6
I'll throw in my 2 cents.
我会投入2美分。
First of all, I'll agree that setting some sort of arbitrary limit is not helpful, such as "Once I have more than 10 statics in a class that's too many!". Refactor when it makes sense but don't start doing it just because you've hit some imaginary boundary.
首先,我同意设置某种任意限制是没有用的,例如“一旦我在一个类中有超过10个静态,那就太多了!”。当它有意义时重构,但不要因为你遇到一些想象的边界而开始这样做。
I wouldn't 100% agree with Brubaker's comment about stateful vs. stateless - I think the issue is more about classes vs instances. Because a static method can change the value of another static property which is a stateful change.
我不会100%同意Brubaker关于有状态与无状态的评论 - 我认为问题更多的是关于类与实例。因为静态方法可以更改另一个静态属性的值,这是一个有状态的更改。
So, think of it like this - if the method/property is of or pertaining to the class, then it should probably be static. If the method/property is of or pertaining to an instance of the class, it should not be static.
所以,想想这样 - 如果方法/属性属于或属于类,那么它应该是静态的。如果方法/属性属于或属于类的实例,则它不应该是静态的。
#1
Personally I find that any number of static methods are a sign of trouble. If your class has instance methods and static methods, then most likely you could split the class into two separate entities and change the static methods to instance methods.
就个人而言,我发现任何数量的静态方法都是麻烦的表现。如果您的类具有实例方法和静态方法,则很可能您可以将该类拆分为两个单独的实体,并将静态方法更改为实例方法。
Think of a class as a special kind of object, with the distinctive property that it is global by nature. Since it's a global variable, it implies a very strong level of coupling, so you would want to reduce any references to it. Static members will need to be referred, meaning that your code will get a strong level of coupling to the class.
将一个阶级视为一种特殊的对象,具有独特的属性,它本质上是全球性的。由于它是一个全局变量,它意味着非常强的耦合级别,因此您希望减少对它的任何引用。需要引用静态成员,这意味着您的代码将获得与类的强大耦合程度。
#2
I'd have to agree with Brubaker and add that to my thinking it isn't the number of methods so much as the functionality of said methods. If you start thinking that your class has to many methods (static or otherwise) then you might find they can be re-grouped and refactored into a more intuitive architecture.
我不得不同意Brubaker的意见,并补充一点,我认为这不是方法的数量,而是所述方法的功能。如果您开始认为您的类有许多方法(静态或其他方法),那么您可能会发现它们可以重新分组并重构为更直观的体系结构。
#3
The first indicator I use when determining if I have to many static methods is if the methods functionality is not stateless. If the static methods change the state of the object they reside in, they probably shouldn't be static.
我在确定是否需要许多静态方法时使用的第一个指标是方法功能是否为无状态。如果静态方法改变了它们所在对象的状态,它们可能不应该是静态的。
#4
I agree with BaileyP and I'll add my couple of pennies:
我同意BaileyP,我会加上几个便士:
I always work with the idea that a class should have a single reason for existing; it should have one job that it does, and it should do it well. After deciding that, and figuring out what the interface to that class should be, I go through and mark any functions that don't change the state of an instance of the class as static.
我总是认为一个班级应该有一个存在的理由;它应该有一份工作,它应该做得很好。在确定并确定该类的接口应该是什么之后,我会通过并标记任何不会将类实例的状态更改为静态的函数。
#5
If you want to build reusable and testable code, you should avoid static methods altogether. Code which calls static methods (or constructors of non-data-like classes) cannot be tested in isolation.
如果要构建可重用且可测试的代码,则应完全避免使用静态方法。调用静态方法(或非类数据类的构造函数)的代码无法单独测试。
Yes, you will have to pass around alot more objects if you eliminate static methods. This is not necessarily a bad thing. It forces you to think about the boundaries and cooperation between your components in a disciplined way.
是的,如果你消除静态方法,你将不得不传递更多的对象。这不一定是坏事。它迫使您以纪律的方式思考组件之间的界限和合作。
#6
I'll throw in my 2 cents.
我会投入2美分。
First of all, I'll agree that setting some sort of arbitrary limit is not helpful, such as "Once I have more than 10 statics in a class that's too many!". Refactor when it makes sense but don't start doing it just because you've hit some imaginary boundary.
首先,我同意设置某种任意限制是没有用的,例如“一旦我在一个类中有超过10个静态,那就太多了!”。当它有意义时重构,但不要因为你遇到一些想象的边界而开始这样做。
I wouldn't 100% agree with Brubaker's comment about stateful vs. stateless - I think the issue is more about classes vs instances. Because a static method can change the value of another static property which is a stateful change.
我不会100%同意Brubaker关于有状态与无状态的评论 - 我认为问题更多的是关于类与实例。因为静态方法可以更改另一个静态属性的值,这是一个有状态的更改。
So, think of it like this - if the method/property is of or pertaining to the class, then it should probably be static. If the method/property is of or pertaining to an instance of the class, it should not be static.
所以,想想这样 - 如果方法/属性属于或属于类,那么它应该是静态的。如果方法/属性属于或属于类的实例,则它不应该是静态的。