簡體   English   中英

在這種情況下應該使用接口還是抽象類?

[英]Should I use an interface or abstract class in this scenario?

我有一個帶有幾種方法的類,其中一個是Save()方法。 我想使用Save的不同實現:Save to DB,Save to File等。因此,這是一個類:

MyClass 
  Add()
  Remove()
  Save()

添加和刪​​除實現對所有人都是通用的。 只有保存會有所不同。 在這種情況下,使用另存為抽象方法來創建抽象類是否更合適? 還是使用界面有什么好處? 如果要在此處使用接口,則需要將添加和刪除的實現復制到所有實現該接口的類中,對嗎? 這里只具有一個帶Save方法的ISave接口是沒有意義的,因為我所有實現的類仍需要定義Add和Remove嗎?

只是試圖更好地了解接口和抽象類的用法...

不知道編程語言是否會有所作為,但是我正在使用C#。

調查策略設計模式: http : //en.wikipedia.org/wiki/Strategy_pattern

您可以創建一個ISave接口,並為每種需要使用的保存方法創建此接口的一個實現。 FileSave,DBSave等

您可以將ISave參數添加到MyClass的構造函數中,然后根據要使用的保存方法將正確的實現傳遞給您的類。

在您的特定情況下,我建議您使用Abstract類。 根據MSDN 針對抽象類與接口的建議,該建議適用於您的方案:

  • 如果要在組件的所有實現之間提供通用的實現功能,請使用抽象類。 抽象類允許您部分實現您的類,而接口不包含任何成員的實現。

在您的Abstract類中,您可以為“ Add”和“ Remove”方法提供功能,並使實現者需要使用abstract(或VB中的MustOverride)重寫Save方法。

請參閱完整的文章以獲取更多信息。

我建議兩者都做。 由於兩個派生類之間有許多共同的代碼,因此繼承層次結構是有意義的。 但是,如果您為類提取接口並始終通過該接口訪問它們,則如果您發現需要一個帶有不同方法來添加,保存和刪除的新類,那么它將為您提供將來的靈活性。

兩者都很好。

首先,定義一個接口

public interface IMyInterface
{
    bool Add();
    bool Remove();
    bool Save();
}

然后定義一個抽象類

public abstract MyBaseClass : IMyInterface
{
    public bool Add() { ... }

    public bool Remove() { ... }

    public abstract bool Save();
}

並在實現MyBaseClass的類中實現您的Save變體。

現在,當需要傳遞對象時,請在代碼中的每個位置使用IMyInterface。

這也使您能夠測試事物。 當“添加”和“ Remove命中數據庫以從表中添加/刪除內容時,測試變得困難。 然后,您需要設置一個測試數據庫環境,將測試指向該環境,並且必須確保在運行測試時始終在干凈的表上進行操作。 但是,如果您只想測試正在調用Add函數的行為,當Add返回truefalse時,行為會有所不同

public class Foo
{
    public int AddRange(MyBaseClass my, int count)
    {
        int retval = 0;
        while (count > 0)
        {
            if (my.Add())
                ++retval;
            --count;
        }
        return retval;
    }
}

由於Add已綁定到MyBaseClass ,因此現在很難測試。 它會擊中數據庫以及在測試過程中可能可靠的所有內容。 但幸運的是,您的使用接口。 因此,將AddRange的簽名AddRange

public int AddRange(IMyInterface my, int count);

並定義您的測試

[TestMethod]
void AddRangeReturns0ForFailedAdd()
{
    var foo = new Foo();
    Assert.AreEqual(0, foo.AddRange(new Fail(), 0));
    Assert.AreEqual(0, foo.AddRange(new Fail(), 1));
    Assert.AreEqual(0, foo.AddRange(new Fail(), 100));
}

class Fail : IMyInterface
{
     public bool Add() { return false; }

     public bool Remove() { return false; }

     public bool Save() { return false; }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM