2017-01-05 154 views
0

我相信這是重複的,但我不確定我在尋找正確的答案。或理解它回答我的問題。 對於1我認爲我使用我的界面錯誤。對於1我打破了固體的規則,並試圖清理它。例如IReelWindow。我在那裏特定的東西ReelWindowTumble,其他ReelWindows不使用和拋出未實現的錯誤。我開始把它分解成多個接口,但發現我不再能夠訪問ReelWindowTumble的功能,即使我爲ITumble創建了一個新接口,並且仍然繼承了IReelWindow。問題出在功能代碼中。實現泛型類型傳遞

public interface IReelWindow 
{ 
    //stuff declared 
    void PopulateWindowTumble(); 
    void PopulateWindow(int[] currentStops); 
} 
public class ReelWindow : IReelWindow 
{ 
// implements most of it throwing exceptions when I don't use it. 
    public void PopulateWindow(int[] currentStops) 
    { 
    } 
    public void PopulateWindowTumble() 
    { 
     throw new NotImplementedException(); 
    } 
} 
public class ReelWindowTumble : IReelWindow 
{ 
// implements most of it throwing exceptions when I don't use it. 
    public void PopulateWindow(int[] currentStops) 
    { 
    } 
    void PopulateWindowTumble() 
    { 

    } 
} 
public class ReelWindowIndependent : IReelWindow 
{ 
// implements most of it throwing exceptions when I don't use it. 
    public void PopulateWindow(int[] currentStops) 
    { 
    } 
    public void PopulateWindowTumble() 
    { 
     throw new NotImplementedException(); 
    } 
} 

下面我宣佈一個新IReelWindow和基於客戶端輸入創建一個新的ReelWindow。這工作正常,因爲我只是想通過IReelWindow我想使用ReelWindow。 我不認爲這是我的界面的正確用法。如果我使用ICloneable,我不會聲明ICloneable的新對象並將其傳遞。 但我的意圖是創建一個通用ReelWindow類型。我不在乎客戶端創建什麼類型的窗口。我只是想強制執行它應該具有的功能,因爲我專門使用它們。
如何聲明一個通用的ReelWindow,我可以傳遞而不創建多個相同但功能強大的函數?

public static IReelWindow CreateReelWindow(WindowType userSelectedWindowType, Paytable paytable) 
{ 
    IReelWindow _reelWindow; 
    if (userSelectedWindowType == WindowType.Standard) 
    { 
     _reelWindow = new ReelWindow(paytable.ColLengths, paytable.ReelContainer.Reels, paytable.WindowWidth,      paytable.Lineset, paytable.ReelContainer.TotalPhysicalReelStop); 
    } 
    else if (userSelectedWindowType == WindowType.Tumble) 
    { 
     _reelWindow = new ReelWindowTumble(paytable.ColLengths, paytable.ReelContainer.Reels, paytable.WindowWidth, paytable.Lineset, paytable.ReelContainer.TotalPhysicalReelStop); 
    } 
    else if (userSelectedWindowType == WindowType.Independent) 
    { 
     _reelWindow = new ReelWindowIndependent(paytable.ColLengths, paytable.ReelContainer.Reels, paytable.WindowWidth, paytable.Lineset, paytable.ReelContainer.TotalPhysicalReelStop, paytable.ReelLengths, paytable.ReelStarts); 
     } 
     else 
      throw new ApplicationException("Unknown window type selected by user. Cannot continue."); 
     return _reelWindow; 
    } 

在我的代碼後來我用reelwindows,只有在「IReelWindow」通過我不在乎什麼類型reelwindow的,該函數將相應地使用它。

public abstract class AEval 
{ 
    public abstract double Evaluate(IReelWindow reelWindow, ref string flags, int currentStopsWeight); 
    public abstract double EvaluateVerbose(IReelWindow reelWindow, ref string flags, int currentStopsWeight); 
} 
+1

你說得對,NIE從接口實現是一種代碼味道,但沒有更多的接口細節,它的用法很難有效地回答你的問題。 – Jamiec

回答

0

您繞過物體是_reelWindow,雖然它實現IReelWindow,它不是一個IReelWindow對象。相反,它是您的派生類型之一:ReelWindow,ReelWindowTumble,ReelWindowIndependent等。這些派生類型中的每一個都應該由客戶端對待(如您所記下的)。

讓我們假裝ReelWindow從接口實現2種方法,ReelWindowTumble從接口實現3種方法,ReelWindowIndependent從接口實現10種方法。該界面最多可以實現10種方法。

使用你的例子的語言,這意味着ReelWindow將有8個方法帶有NotImplementedException(NIE),ReelWindowTumble將有7個方法NIE,而ReelWindowIndependent有0個方法NIE。

你的客戶端代碼如何?那麼,爲了使所有這些有意義,您的客戶端代碼應該在使用_reelWindow時調用所有10種接口方法。這也意味着,使用我的例子,ReelWindowIndependent應該可以很好地處理客戶端代碼,因爲它沒有NIE方法。

我會說你真正的問題是NIE的。除去這些異常並返回null。然後,在您的客戶端代碼中,在控制流程期間,您可以添加語句以「如果返回的對象爲null,跳過此部分」。請記住,所有的對象都是從'object'繼承的。那些強類型的返回對象也可以作爲'object'返回。這意味着任何強類型對象都可以設置爲null。重複一遍:嘗試爲強類型返回值的方法返回null值,並在客戶端代碼中處理null。現在,如果接口方法沒有返回 - 它被標記爲void - 那麼你不需要擔心在你的客戶端代碼中檢查null,你也不需要NIE:方法可以留空,當從字面上調用時什麼也不做。如果你仔細想想,你可能會爭取不使用強類型返回值的接口設計。這就是Jamiec的評論:我們需要更多地瞭解界面。

+0

所以我正確使用我的界面?我只需要處理NIE的不同呢?看起來就像處理程序崩潰一樣,處理得更好。 – user3281977

+0

不,它不是一樣的味道。試想一下名爲IDriveCar的界面。你有兩輛車:AutomaticCar和StandardCar。他們兩人將實施IDriveCar。假設他們都實現了標題爲ShiftGears()的方法;但自動駕駛汽車將以其實施方法ShiftGears()......「無所事事」......在所有自動汽車之後。 StandardCar將用「用手將變速桿換到下一檔」來實現它,而AutomaticCar將以「什麼都不做」的方式來實現它 - 它不會做的就是拋出一個NIE並使車撞車! – sapbucket

+0

好的。我得到那件作品。但是當你宣佈新車(自動或標準)時,你是否宣佈新的IDriveCar?或者你宣佈新的AutomaticCar由於我駕駛汽車而被迫實施ShiftGears()。 – user3281977