2013-04-02 72 views
1

我絕對無法解釋我在標題中的含義。這個問題要麼太愚蠢,要麼太複雜,但最終的結果是我找不到合適的設計模式。如何創建接口的實現,即使用其他接口的特定實現?

因此,我們假設我們有類A,它包含對接口B的引用。計算過程確定B的哪個實現是適當的,並實例化一個新對象。到目前爲止這麼好(我認爲)。

現在B有一個基於一組參數的方法。對象A擁有一組默認參數,但任何一組都可以按需提供。棘手的部分是參數在接口B的實現中完全不同。事實上,這些參數本身具有不同的對象,它們各自的方法在B的不同實現方式中是不同的。對我來說,最初的方法是創建一個接口C參數,然後爲B的每個實現(它是一對一的關係)創建一個C的實現,但這看起來不正確。如果不是別的,在B的每個獨特實現中,我必須將C投影到調用其獨特函數所需的相應實現上。

人們只能假設有更漂亮的方式!有任何想法嗎?

回答

2

正如在其他答案中指出的,B不是一個合適的界面(在道德意義上)。如果這些PARAMS實在無法進行的每項B實施的一部分,那麼你仍然可以通過抽象的細節客場實現了正確的接口:

interface BWrapper { 
    public void doSomething(); 
} 

class ConcreteB { 
    public static class Params { ... } 

    public class Wrapper implements BWrapper() { 
     public Wrapper(Params params) { this.params = params; } 
     @Override 
     public void doSomething()  { ConcreteB.doSomething(params); } 
     private final Params params; 
    } 

    public void doSomething(Params params) { ... } 
} 


class A { 
    void setWrapper(BWrapper wrapper) { this.wrapper = wrapper; } 
    void foo()      { wrapper.doSomething(); } 

    private BWrapper wrapper; 
} 

... 

A a = new A(); 

ConcreteB.Params p1 = new ConcreteB.Params(); 
a.setWrapper(new ConcreteB.Wrapper(p1)); 
a.doSomething(); 

ConcreteB.Params p2 = new ConcreteB.Params(); 
a.setWrapper(new ConcreteB.Wrapper(p2)); 
a.doSomething(); 
+0

因此,我在其各自的類中實現了每個Param,並通過一個包含B和一個默認Param對象的實現的包裝向外界展示。那麼它不是最直觀的實現,但如果你認爲它是正確的,我可能會去做! –

+0

@Andreas:我不是說這是唯一的方法。這只是一個例子,你如何呈現一個一致的界面而不需要醜陋的表演。 –

+0

我對這個實現有兩個問題。首先是在包裝內部,除非'doSomething'是靜態的,否則我不能做'ConcreteB.doSomething(params)'!那麼我也想知道,你爲什麼最終做出「params」? –

5

B是不正確的接口,如果用戶需要調用它的方法具有依賴於底層實現的特定參數。你應該重新考慮你的設計。爲什麼A甚至可以訪問這些參數?他們屬於每個B實現?

+0

這些都很好好的問題。我會帶來一個等效的例子。假設B是形狀。他們都執行相同的操作,.volume(Param)。假設我不想要明顯的體積,但是基於一些參數的體積,它們的形狀和形狀是非常不同的?任何關於如何更好地建模的見解? –

+0

很難知道沒有你想要做的細節,但我會說一個形狀,'音量'應該沒有參數。如果你正在試圖計算一個形狀的體積,你不想爲它提供它應該已經知道的東西。 – artbristol

+0

那麼如果你想在不同的壓力下用不同的氣體膨脹形狀後計算體積,同時使形狀的不同表面具有不同的靈活性並改變氣體入口點。由於不是所有的形狀都具有相同的曲面,我猜測你需要不同的參數。有很多變化是最重要的,例如想象一下由螺旋線製成的網狀物。 –