2017-05-03 66 views
1

我正在尋找關於以下方面的一些方向,我是OOP的新手,但到了那裏卻認爲我的理解力不足導致我陷入了兔子洞或者我只是過多地思考事物,併成爲肛門。一類中的可選依賴關係

基本上我有一個叫做「CurlRequest」的主類,唯一的目的是執行curl請求,提供一個url和params它返回我一些html。這門課的作品和功能如預期,我很滿意。

我將這個類用於一些項目,但對於其中一個我想跟蹤我的請求的性能。嘗試,失敗,傳遞等等,所以我創建了一個靜態類來管理我的所有計數器。我在我的CurlRequest類的不同區域放置類似以下的計數器引用。

PerformanceTracker::Increment('CurlRequest.Attempted'); 
PerformanceTracker::Increment('CurlRequest.Passed'); 
PerformanceTracker::Increment('CurlRequest.Failed'); 

我有這些大約10個左右我的同班同學捲曲請求期間跟蹤各種事情,我也用我的PerformanceTracker類我做其他類。

然而,像上面提到的,我只是想爲我的項目之一做這件事,所以找到我的自我的情況下,我的原始CurlRequest類和改變與性能計數器在它的情況。

我的問題是,他們是一種方式,我可以使用相同的類爲任何項目,並選擇使用PerformanceTracker類或不。我想到的顯而易見的方式是將一個$選項參數傳入該類,然後在所有計數器周圍都有if語句,但不禁讓人想起它的混亂。

  if ($this->options['perfCounter'] == true) { 

       PerformanceTracker::Increment($this->owner . '.CurlRequest.Failed'); 

      } 

這也增加了很多額外的代碼給這個類。

回答

1

我建議把if語句在一個單獨的方法

如果你發現你想與不同的跟蹤性能,而不是調用這個方法您的通話來

PerformanceTracker::Increment(...); 

而且你項目將您的構造函數更改爲接受可調參數可能會很有用,這樣可以將CurlRequest類本身的實際實現外化。

public function __construct(..., callable performanceHandler) 

然後當你實例化類:

$curlRequest = new CurlRequest(..., function($outcome) { 
    //your implementation 
}); 
1

您可以使用繼承和創建委託給父母的方法之前執行日誌記錄的子類:

class PerformanceTracker 
{ 
    static function Increment($s) 
    { 
     echo $s; 
    } 
} 

class CurlRequest 
{ 
    function get($url){ 


     //preform curl request, save html to variable etc 
     //dummy vars used here so working example code 
     $html = 'html here'; 
     $curlError = false; 
     if($curlError){ 
      $this->error($curlError); 
     } 


     return $this->success($html); 
    } 
    protected function success($html) 
    { 
     return $html; 
    } 

    protected function error($curlError) 
    { 
     throw new Exception($curlError); 
    } 

} 

class LoggingCurlRequest extends CurlRequest 
{ 


    function get($url) 
    { 
     PerformanceTracker::Increment('CurlRequest.Attempted'); 
     return parent::get($url); 
    } 

    function success($html) 
    { 
     PerformanceTracker::Increment('CurlRequest.Passed'); 
     return parent::success($html); 
    } 

    function error($curlError) 
    { 
     PerformanceTracker::Increment('CurlRequest.Failed'); 
     parent::error($curlError); 
    } 
} 



$lcr = new LoggingCurlRequest(); 

$lcr->get('unused in example'); 

,因爲我有使用具有最少代碼的虛擬類來演示該技術的好處可能不明顯,但在真實代碼中,CurlRequest類中的方法將更加複雜,但是方法日誌記錄類將保持爲兩行,帶有日誌功能和對父方法的調用。

使用這種技術,您可以修改父類而不影響派生類(提供的方法簽名不會改變),可以創建其他派生類(如何CachingCurlRequest)等

對於OOP的全部好處,你應該考慮依賴注入和接口

1

從您可以使用'Null' object pattern一個面向對象的觀點。這僅僅意味着CurlRequest類所使用的依賴是抽象的(可能是一個接口?)。然後,您將擁有兩個具體的PerformanceTracker實現:您今天擁有的一個實例,它不做任何事情(它沒有任何行爲)。在實例化CurlRequest類時,通過這種方式爲一個項目使用具有行爲的具體實現,對於所有其他項目,它將使用沒有行爲的具體實現。所有CurlRequest的代碼看起來一樣,但它必須根據它是使用

上具體實現不同的行爲