2012-02-02 85 views
4

主題說,它已經:OOP設計:接口的方法與實現相關的參數

我想現在大概如下設計問題:我定義一個接口,它包含各種方法的一個特定類型的對象。 現在我有這個問題,這個接口的不同實現,需要額外的/不同的方法參數(因爲它們的實現方式使得這個必要),我不能將它納入接口,因爲它們不是通用的全部接口-implementations。

現在我意識到接口實現可以帶有自己的屬性文件,從那裏加載它們的附加參數,但是如果這些參數需要在運行時傳遞呢?

目前我只能想到在Map<String, Object> parameters通過克服這個問題的 - 因爲JDK-類,如DocumentBuilderFactory正在做的通過提供像setAttribute(String attName, Object attValue)方法本 似乎是一個可行的辦法來解決這個問題非常類似的東西。 不過,我會對其他人如何解決這樣的問題感興趣嗎?

我不想從接口派生並添加其他方法,因爲在我的情況下,我將不得不從基接口的方法拋出NotImplementException

UPDATE:地圖的方法的

什麼能最終的問題?如果不能使用其他參數,實現類可以完全忽略它。 其他人可能會檢查Map是否包含所需的參數名稱,檢查其值的類型並在有效時使用它們,如果不是,則拋出異常。 我也看到了這一點正在使用抽象類的JAXBContext,所以它似乎是一個常見的方法..

UPDATE

我決定去地圖的方法,因爲我沒有看到任何明顯的缺點,它也被用於JDK(是的,我知道這並不意味着太多:) 因爲我不能接受關於這個問題的答案,我只會upvote。感謝您的輸入!

問候,

--qu

+0

這個信息是一種方法需要的東西,或是對象需要執行它的動作的東西?舉一個具體的例子。使用** Map **是一個糟糕的設計決定。 – 2012-02-02 12:55:02

+0

@MaurícioLinhares我意識到這個解決方案遠不是最優的(這就是爲什麼我問這個問題),但以DocumentBuilderFactory爲例 - 接口對於所有可能的DOM解析器是相同的,但不同的DOM解析器實現提供了不同的功能/參數,你永遠不可能全部納入接口,但你需要一種方式來在運行時以某種方式傳遞這些參數 - 我提到了JDK如何解決這個問題... – quaylar 2012-02-02 13:02:31

+1

想一想,這是一個**初始化**過程。工廠唯一的目的是創建一個可以完成工作的新對象,它的**接口**根本不會改變。你想要的是別的東西,你想把它添加到你的**接口方法**中。如果你想要的是真正在初始化過程中設置對象,那麼創建這些對象的構造函數參數就是了。 – 2012-02-02 13:09:51

回答

1

無法您設計您的擴展(超)接口子接口?無論如何,我看到一個設計問題,如果你需要一個不同的參數取決於實施方法!

編輯:代碼澄清

interface CommonBehaviour 
{ 
    void methodA(int aParam); 
} 

interface SpecificBehaviour extends CommonBehaviour 
{ 
    void methodB(int aParam, int anotherParam); 
} 

class SpecificBehaviourImpl implements SpecificBehaviour 
{ 
    void methodA(int aParam) 
    { 
     //do something common 
    } 

    void methodB(int aParam, int anotherParam) 
    { 
     //do something specific 
    } 
} 

CommonBehaviour myObj = new SpecificBehaviourImpl(); 

編輯: 「使用命令對象可以更容易地構建需要委託,順序或執行方法調用以通用部件:您可以從命令模式中受益而不需要知道方法的所有者或方法參數。「 (來源:維基百科)

我不認爲Map方法來得到什麼好處,我可以接受它作爲一個修復現有的代碼,將讓你有任何的參數數量和類型的,但沒有正規檢查!你試圖給出定義一個變量,運行時狀態的共同行爲(接口方法)。

+0

我可以,但如果我這樣做是因爲實現不能實現基接口的方法,我仍然需要實現它們,但拋出一個NotImplementedException - 一個設計,我也不喜歡太多.. – quaylar 2012-02-02 13:05:42

0

您可以反問題,並實現對這些對象,他們可以查詢的用戶界面附加參數?

因此,當您實例化這些實現通用接口的對象時,還可以通過(例如給它們的構造函數)一個對象,它提供了一種訪問他們可能需要的額外參數的方法。

說你的接口有一個方法「DoSomething的」以參數「A」,但你需要知道什麼是「B」就是這個「DoSomething的」方法中的實現。它會在你提供給它的構造函數的對象上調用'getB'來獲取這些信息。

+0

你能詳細說明這一點嗎?我還沒有完全明白這個主意。 – quaylar 2012-02-02 13:00:10

+0

@quaylar - 這有幫助嗎? – sje397 2012-02-02 13:06:17

+0

對我來說,這似乎只是增加了一層間接性。接口方法的客戶端知道有一組可能的參數,但並不是所有的實現都「理解」了所有這些參數。 在創建對象時,這些參數是未知的,所以我不能通過構造函數傳遞它們。它們被接口客戶端接收到,所以也沒有辦法指定委託對象,因爲你建議.. – quaylar 2012-02-02 13:13:19

0

你應該代表介紹了超級組可能的參數參數對象

+0

當然,這是最簡單的變體,您可以對它進行子類化,使設計更具可讀性。 – 2012-02-02 13:04:43

1

接口的意義在於讓所有實現都有一些共同點。通過試圖做到這一點,你可以摧毀接口存在的全部原因。

如果您絕對必須這樣做,那麼我以前曾經使用過一種簡單的方法。

我的答案是C++,因爲我只是不那麼流利的其他語言。我確信有一些方法可以在java中實現。

SomeMethod(void* parameterData);

void* parameterData是一個指針,指向包含數據的結構體。在每個實現中,你知道你正在接受什麼。你甚至可以有一個枚舉來告訴你你正在接收什麼樣的數據。

SSomeData* data = (SSomeData)parameterData

編輯:

另一種方法是創建參數一個新的接口:IParameterData
在該界面中,您有2種方法:GetParameter(name)SetParameter(name)
對於主接口的每個實現,您創建IParameterData的實現。

我希望它能幫助

+0

那麼,翻譯成Java,這將是我在我的問題中提到的方法。 – quaylar 2012-02-02 13:06:52

+0

對不起。我沒有意識到你所說的是我說的Java版本。我正在準備另一種方法的編輯。 – Sanctus2099 2012-02-02 13:10:54

+0

感謝您的支持,這與直接傳遞地圖非常相似.. – quaylar 2012-02-02 13:28:47

0

在你的地方,我會考慮尋找適當的設計模式,您的問題,而不是試圖歪曲接口的方法來滿足您的需求。先看看Strategy Pattern

1

你應該只初始化自己特定需要的參數每個繼承人,讓接口方法保持參數少,如:

接口Runnable

public interface Runnable { 
    public abstract void run(); 
} 

實現:

public class MyRunnable { 

    private final String myConcreteString; 

    public MyRunnable(String myConcreteString) { 
     this.myConcreteString = myConcreteString; 
    } 

    public void run() { 
     // do something with myConcreteString 
    } 
} 
+1

這些參數在對象創建時未知... – quaylar 2012-02-02 13:24:09