2015-12-30 30 views
0

我有以下體系結構(的比喻糟糕,但W/E)。多態性和明確鑄造

enter image description here

program和其他邏輯的類我有很多的使用特定類型的手指(MonkeyFinger)的方法。這意味着我必須明確地施放所有這些testMethods。

是否有任何設計模式/解決方案來避免顯式強制轉換?

編輯代碼:

Monkey govi = new Monkey(...) 
Program test = new Program() 
test.testFinger1((MonkeyFinger) govi.GetHand.getFinger) 

...

+0

你能顯示代碼嗎? –

+0

動物一方面只有一個手指? –

+0

@YacoubMassad實際的代碼非常複雜,我添加了一些虛擬代碼。 – RayOldProf

回答

5

你可以嘗試這樣的事情:

public class Animal<TFingerType> where TFingerType : IFinger 
{ 
    Hand<TFingerType> GetHand() 
    { 
     //... Do something 
    } 
} 

public class Monkey : Animal<MonkeyFinger> { } 
public class Hand<TFingerType> where TFingerType : IFinger 
{ 

} 
public interface IFinger 
{ 

} 
public class MonkeyFinger : IFinger { 
} 

在給定的例子至少,它沒有任何意義了Monkey返回包含HumanFinger個手。手本身實際上是由它的手指類型來定義的。

那麼你的代碼變成:

Monkey govi = new Monkey(...) 
Program test = new Program() 
test.testFinger1(govi.GetHand.getFinger() /* getFinger here returns a MonkeyFinger */) 

注意,手指仍舊IFingers,並且可以在上下文中使用,但這種方法也提供了具體類型的手指。

+0

這是一個非常好的解決方案,但事實證明,我必須對現有代碼進行大量更改才能實現此目的。在你看來,這個解決方案比明確的施放還是有一些優點,或者改變現有的工作代碼是一個壞主意? – RayOldProf

+1

@RayOldProf這取決於,如果沒有看到實際的代碼就很難做出調用。如果你只是在進行測試,我會說這可能是不值得花時間改變的,因爲你說這需要大量的努力。然而,如果你在真正的代碼中投射,這可能是一個問題(因爲它現在是完全可能的,一個'Monkey'返回一個''Hand',它具有'HumanFinger'而不是'MonkeyFinger')。使用模板意味着你可以保證從Monkey的手中得到一個MonkeyFinger。 – Rob

0

我認爲這是最好的創建做檢查你的方法。是的,如果你想測試一些假設(比如只有猴子手指的猴子),那麼投射是必要的。

喜歡的東西:

public static T TestAndConvert<T>(object o) 
{ 
    Assert.IsInstanceOfType(o, typeof(T)); 

    return (T)o; 
} 

在這裏,您首先檢查,如果該類型是否正確,然後返回一個類型的實例。這樣你就可以確定這個類型是正確的,並且你有正確的測試。

使用它在您的測試呼叫:

testFinger1(TestAndConvert<MonkeyFinger>(finger)); 

(從你的圖我不知道,如果你使用一個自動化測試框架,就像在Visual Studio單元測試,我建議這樣做)

+1

不知道這個斷言提供了什麼好處。演員操作員會通過拋出異常來讓您知道演員是否有效。 –

+0

它會在測試概覽中給出更好的指標。一個例外通常會告訴你測試中存在代碼錯誤。斷言會告訴你,你已經想到了它,並且你可以預料到這會出錯。 –

0

是否真的需要通過具體的手指來測試方法?當你使用接口時,你需要定義一個每個實現應該遵循的合同。你可以在子類中擴展父類行爲(或者替換它,但它不與Liskov substitution principle對應),但只測試合同,那麼爲什麼你需要通過測試方法中的IFinger的MonkeyFinger?