2009-01-14 71 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。調用靜態方法(或非類數據類的構造函數)的代碼不能單獨進行測試。

是的,如果消除靜態方法,您將不得不傳遞更多的對象。這不一定是壞事。它迫使你以一種嚴謹的方式思考你的組件之間的界限和合作。