2009-01-14 268 views
3

UPDATE:改写一个问题,在这个类结构中是否存在太多静态方法(我意识到现在只有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类中?

回答

1

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

认为一个类是一种特殊的对象,具有独特的属性,它是全球性的。由于它是一个全局变量,它意味着非常强大的耦合级别,因此您希望减少对它的任何引用。静态成员将需要被引用,这意味着你的代码将获得与班级的强烈联系。

3

当确定我是否需要很多静态方法时,我使用的第一个指示器是方法功能不是无状态的。如果静态方法改变它们驻留的对象的状态,它们可能不应该是静态的。

+0

微软笑话的提醒,技术上正确,但在这种情况下,不是非常有用。主要是因为这些方法已经不能修改对象的状态,他们只是返回对象或创建一个全新的对象。但无论如何thx答案。 ;-) – 2009-01-14 22:06:13

+0

够公平的。我不熟悉php使用过去的概念信息在这种情况下=( – 2009-01-14 22:12:18

+0

gabriel,你问“什么时候太多?”不看我的代码是这么多... – cgreeno 2009-01-14 22:14:52

4

我不得不同意Brubaker的观点,并补充说我认为这不是方法的数量,而是所述方法的功能。如果你开始认为你的类需要很多方法(静态或其他方法),那么你可能会发现它们可以重新分组并重构为更直观的体系结构。

1

我会投入我的2美分。

首先,我会同意设置某种任意限制是没有帮助的,例如“一旦我的班级中有超过10个静态值,太多了!”。有意义时重构,但不要仅仅因为你碰到了一些虚构的边界就开始做。

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

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

2

我同意BaileyP,我会加入我的几个便士:

我一直的想法,一类应该有现有的理由只有一个工作;它应该有一份工作,它应该做得很好。在决定之后,并确定该类的接口应该是什么,然后标记所有不会将该类的实例的状态更改为静态的函数。

2

如果你想构建可重用和可测试的代码,你应该avoid static methods altogether。调用静态方法(或非类数据类的构造函数)的代码不能单独进行测试。

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