接口是不能直接用於代碼重用。他們是爲了抽象。它們啓用使用該模板的類來檢查接口而不是基本模板類。這樣它就將接口聲明中的實現分開了。
因此,如果您的方法對template
類執行了某些操作,那麼檢查實例template
的對象將難以編碼對該類的依賴性。但事實上,你並不在乎你得到的是什麼課程,你只是在乎它是否遵守了界面(因爲這就是你所打的所有東西)。
public function foo(Template $template) {
VS:
public function foo(iTemplate $template) {
現在,只要代碼複用,接口是不是真的設計了點。繼承通常是。基本上認爲繼承是擴展抽象。讓我舉個例子:
如果你要爲鳥類創建一組類,你可以通過繼承來處理它,如果沒有它的話。讓我們來看看我們如何做到這一點沒有:
interface iBird {
public function fly();
public function speak();
public function swim();
public function walk();
}
class Duck implements iBird {
public function fly() {
//Fly here
}
public function speak() {
// Quack here
}
public function swim() {
//Swim here
}
public function walk() {
//Walk here
}
}
class Turkey implements iBird {
public function fly() {
//Fly here, but limited
}
public function speak() {
//Make turkey sound here
}
public function swim() {
throw new Exception('Turkeys can not swim!');
}
public function walk() {
//Walk here
}
}
現在,這是一個簡單的例子,但是你可以看到,在這兩個鳥,walk()
功能將可能是相同的(並因此違反DRY)...
讓我們來看看如何看起來與單層繼承:
abstract class Bird implements iBird {
public function fly() {
//Fly here
}
abstract public function speak();
public function swim() {
//Swim here
}
public function walk() {
//Walk here
}
}
class Duck extends Bird {
public function speak() {
//Quack here
}
}
class Turkey extends Bird {
public function speak() {
//Make turkey sound here
}
public function swim() {
throw new Exception('Turkeys can not swim!');
}
}
現在,你可以看到,我們只是重新使用的方法3!我們沒有聲明speak()
,因爲它會一直被覆蓋(因爲沒有兩隻鳥聽起來一樣)。
聽起來不錯吧?那麼,根據我們的需要,我們可能需要添加其他抽象類型。因此,我們可以說我們製作了許多不同類型的鳥類......我們會有一些不會游泳的,因此我們可能會創建一個抽象類NonSwimmingBird
,它擴展Bird
,但是會爲我們引發異常。或者NonFlyingBird
或ShortRangeBird
...
現在,儘管代碼重用,但我們在其他區域遇到了問題。假設我們有一隻不會飛翔或游泳的鳥。我們繼承什麼課程?無論哪種方式,我們都在複製代碼。所以我們需要找到另一條出路。那麼,我們該怎麼做呢?通過Design Patterns ...我們可以使用裝飾器模式來實時添加這些特徵,而不是直接繼承。 (還有其他的模式可以用在這裏,重點是要證明單獨的繼承並不適合所有的需求,單獨的模式也不會,你需要一個好的架構來根據你的確切需求來使用兩個世界) ...
問題是,這一切都取決於您的需求。如果你只有2個「班級」的對象,那麼你將構建一個比如果你計劃擁有數千個更簡單的東西。我寫在這裏的目的是爲了演示如何使用直接繼承來實施一些DRY主體(但也包括直接繼承如何導致代碼重複)。最重要的是,不要因爲你不想重複自己而堅持DRY。堅持DRY,但要確保你在合理的地方進行組合和擴展,否則你會造成自己的維護頭痛。堅持Single Responsibility Principal,你應該沒問題...
你能告訴我你在哪裏找到那個代碼嗎?我正處於學習階段,我希望通過實例學習。 – dole 2011-02-25 18:27:04