2012-12-20 63 views
7

我正在開發一個正在注入Logger對象的服務,但我可以有兩種不同類型的記錄器,我計劃使用syslog記錄器和隊列消息系統記錄器。這可能嗎?是否可以在PHP界面中使用不同參數定義方法?

的想法是具有接口:

class Syslogger implements Loggable 
{ 
    public function log() 
    { 
     ... 
    } 
} 

class QMSLogger implements Loggable 
{ 
    public function log($queueName) 
    { 
     ... 
    } 
} 

我能來與被具有陣列作爲參數,並使用它的唯一方法:實現該接口

interface Loggable 
{ 
    public function log() ; 
} 

和2類在一個類和不使用另一個......但這是有點臭:P

+5

如果該方法在一種情況下接受參數而不在另一種情況下接受參數,它不是相同的接口! – deceze

+0

是的,我想這是更正確的方法,但我想能夠注入任何一類,以便能夠更改日誌記錄系統......我想我錯了 – Khriz

+2

那麼這實際上可能的情況下'$ queueName'默認爲NULL ('公共函數日誌($ queueName = null){...}')但我同意在這裏欺騙。 –

回答

8

正如評論中所述,這不是相同的接口。如果你不能概括所有可能的記錄器實現的接口,使實例構造函數的配置差異部分:

class QMSLogger implements Loggable { 

    protected $queueName; 

    public function __construct($queueName) { 
     $this->queueName = $queueName; 
    } 

    public function log() { 
     ... 
    } 

} 
8

你問如果這是可能的:的確是這樣,但是......

如果您實現一個界面,你必須尊重其合同

interface Loggable 
{ 
    public function log(); 
} 

此接口的合同是你可以調用log()不帶任何參數

爲了尊重,可以使參數可選:

class QMSLogger implements Loggable 
{ 
    public function log($queueName = null) 
    { 
     ... 
    } 
} 

這是perfectly valid PHP並尊重里氏替換原則。當然,在對接口進行編碼時不能使用該可選參數,否則顯然會中斷接口。只有在使用實現時(例如,在與QMSLogger緊密耦合的代碼的某些部分中),此參數纔有用。

但是,這可能不是解決方案,因爲$queueName似乎是一個配置值,它可能會更好地將它傳遞給類的構造函數(如其他答案中所述)。

1

您也可以通過參數數組,這樣你從一方面尊重合同,也可以靈活地與陣列內的任何量插入任何值,檢查了這一點:

abstract class FeaturesAbstract 
{ 
    /** 
    * @param array $paramsArray 
    * 
    * @return mixed 
    */ 
    abstract public function addExecute($paramsArray); 
} 

而實際使用這種方法,你可以發送的參數是這樣的:

$this->abstract->addExecute(array('paramA' => $paramA, 'paramB' => $paramB)); 

然後具體落實中你得到的參數是這樣的:

/** 
    * @param array $paramsArray 
    * 
    * @return void 
    */ 
    public function addExecute($paramsArray) { 

    $a = $paramsArray['paramA']; 
    $b = $paramsArray['paramB']; 
    $c = ... 
} 

祝你好運:)

相關問題