2010-06-09 46 views

回答

9

設計模式不是隨意注入到應用程序中的。他們是設計時間的東西,而不是帕瑪森芝士,它已經烘焙後會灑在代碼上。

這就是說,喬希布洛赫的開創性的有效的Java強烈鼓勵開發人員使用接口共享行爲,而不是使用繼承。這符合我自己的經驗。 ETA:除了其他原因,如果您正在實現一個接口,您可以輕鬆地創建該接口的模擬以用於測試,而不必擔心繼承層次結構的其餘部分。

5

設計模式不會被「注入」到您的代碼中 - 您首先需要注意您的問題類似於許多其他問題解決的問題,並且他們已經提煉出瞭解決問題的模式。最有名的是here

此外,您是否要使用繼承(又名擴展)或接口依賴。通常界面和組成效果更好。

2

這兩個功能並不相互排斥。接口和實現指定類型和與類型的兼容性。繼承允許有效地共享代碼。在經典設計中,類型層次結構使用接口表示,而代碼重用則使用繼承來實現。

+0

你的意思是「這兩個特徵不是*互斥*」嗎? – 2010-06-09 14:12:12

+0

是的(另外11個) – 2010-07-05 11:52:06

1

我確實認爲不應該考慮注入或使用某些設計模式。設計模式旨在解決特定環境中的特定問題。

關於接口和繼承:

接口當你需要運行時多態性正在使用。所以,你定義了一個接口,你可以有多個不同的實現。在客戶端代碼中,您可以將引用聲明爲接口類型。現在,您不必在運行時傳遞給客戶端的實際類型的對象。你只關心在引用上調用方法。

interface Car { 
     void startEngine(); 

     void stopEngine(); 
    } 

    class Maruti implements Car { 

     public void startEngine() { 
      System.out.println("Maruti engine started"); 
     } 

     @Override 
     public void stopEngine() { 
      System.out.println("Maruti engine stopped"); 
     } 
    } 

    class Porsche implements Car { 

     @Override 
     public void startEngine() { 
      System.out.println("Porsche engine started"); 
     } 

     @Override 
     public void stopEngine() { 
      System.out.println("Porsche engine stopped"); 
     } 
    } 

在上面的例子中,作爲客戶端,您只需將引用聲明爲Car類型。在運行時,您可以擁有Maruti對象或保時捷對象,您不在乎。你關心的只是調用startEngine或stopEngine。

繼承通常用於代碼重用性和可擴展性。所以,你在兩個類中有共同的代碼,並且這兩個類似乎都屬於一個通用類型,那麼你可以創建一個父類(有時是抽象的),並將通用代碼移到父類中。這樣你可以擺脫重複的代碼。另一個用例是可擴展性,有時你不能控制類的源代碼,仍然希望添加/更改某些行爲。您可以使用繼承並重寫某些方法。

還有一件東西叫做「組合」這是繼承擴展性的一種優選方式。