2015-05-26 26 views
2

我有一個接口來定義我的記錄\型號分離接口,使他們更通用

public interface IStockItem 
{ 
    string Code { get; set; } 
    string Description { get; set; } 
    decimal FreeStock { get; set; } 
} 

是不是最好把行動統一到另一個界面?

public interface IStockExport 
{ 
    IEnumerable<IStockItem> GetAll(); 
    IEnumerable<IStockItem> GetStockByCode(string code); 
    decimal GetFreeStock(string code); 
} 

public interface IStockImport 
{ 
    void CreateItem<IStockItem>; 
} 

有沒有更好的方法來做到這一點,使其更通用?所以我可以與其他記錄\模型共享操作界面?

其他記錄\模型是SalesOrder,Customer,Address。

整體想法是一個導入\導出程序,它將通過API在多個不同的帳戶包中創建\導出銷售訂單。

+1

可以使界面通用的,但是這可能會或可能不理想。你想支持哪些其他類型?他們邏輯上是否需要相同的合同,但僅在類型上有所不同? –

+1

你最好問她這個問題http://codereview.stackexchange.com/ – Sybren

回答

3

這是一種常見的模式,稱爲Repository Pattern

如果要沿着這條路走下去,你應該建立一個基本接口,Repository<T>,例如:

public interface IRepository<T> 
{ 
    void Insert(T entity); 
    void Delete(T entity); 
    IEnumerable<T> SearchFor(Func<T, bool> predicate); 
    IEnumerable<T> GetAll(); 
    T GetById(int id); 
} 

你將使你的IStockItem實施IEntity接口,以便它可以爲GetById()提供ID ,例如:

public interface IEntity 
{ 
    int ID { get; } 
} 

,那麼你會通過聲明實現類實現了數據類型的存儲庫,如StockItem。它可能會開始有點像這樣:

public class Repository<T> : IRepository<T> where T : class, IEntity 
{ 
    protected Table<T> DataTable; 

    public Repository(DataContext dataContext) 
    { 
     DataTable = dataContext.GetTable<T>(); 
    } 

    ... 

你的代碼,想在一個股票項目的存儲庫,以獲得可能是這樣的:

using (var dataContext = new StockItemDataContext()) 
{ 
    var StockItemRepository = new Repository<IStockItem>(dataContext); 
    ... 

這可能是矯枉過正,你想要什麼,但這是一般的方法。

For full details see this excellent blog post

Also see this example.

這裏是你會如何開始實施這種模式對於你的情況:

public interface IRepository<T> 
{ 
    void Insert(T entity); 
    void Delete(T entity); 
    IEnumerable<T> SearchFor(Func<T, bool> predicate); 
    IEnumerable<T> GetAll(); 
    T GetByCode(string code); 
} 

public interface IStockItem: IEntity 
{ 
    string Description { get; set; } 
    decimal FreeStock { get; set; } 
} 

public sealed class StockItem: IStockItem 
{ 
    public string Code { get; set; } 
    public string Description { get; set; } 
    public decimal FreeStock { get; set; } 
} 

public interface IEntity 
{ 
    string Code { get; } 
} 

public sealed class MyLowLevelDataAccess 
{ 
    public StockItem FindStockItem(string code) 
    { 
     return null; // Call your API here. 
    } 

    public void DeleteStockItem(string code) 
    { 
     // Call your API here. 
    } 

    public void InsertStockItem(StockItem item) 
    { 
     // Call your API here. 
    } 

    public IEnumerable<StockItem> FindAllItems() 
    { 
     return FindItemsMatching(x => true); 
    } 

    public IEnumerable<StockItem> FindItemsMatching(Func<StockItem, bool> predicate) 
    { 
     return null; // Call your API here and return all items matching the predicate. 
    } 
} 

public sealed class StockRepository: IRepository<StockItem> 
{ 
    private readonly MyLowLevelDataAccess _dataAccess; 

    public StockRepository(MyLowLevelDataAccess dataAccess) 
    { 
     _dataAccess = dataAccess; 
    } 

    public void Insert(StockItem entity) 
    { 
     _dataAccess.InsertStockItem(entity); 
    } 

    public void Delete(StockItem entity) 
    { 
     _dataAccess.DeleteStockItem(entity.Code); 
    } 

    public IEnumerable<StockItem> SearchFor(Func<StockItem, bool> predicate) 
    { 
     return _dataAccess.FindItemsMatching(predicate); 
    } 

    public IEnumerable<StockItem> GetAll() 
    { 
     return _dataAccess.FindAllItems(); 
    } 

    public StockItem GetByCode(string code) 
    { 
     return _dataAccess.FindStockItem(code); 
    } 
} 
+0

我不是100%確定如何創建實現類以及如何獲取存儲庫(我瞭解基礎接口部分)。我沒有使用Linq to SQL或Entity Framework。大多數時候獲得庫存物品,我將不得不通過API查詢四個賬戶系統之一。 – user2859298

+0

@ user2859298在這種情況下,您將手動實現獲取實際數據的方法。 –

+0

@downvoter:通常認爲解釋你認爲答案是錯誤的是有幫助的,不僅要教育寫這篇文章的人,還要教育那些讀過它的人。 –

3

你可以使用一個通用的接口,以及:

public interface IRecordExport<T> where T : IRecordBase 
{ 
    IEnumerable<T> GetAll(); 
    IEnumerable<T> GetOneByCode(string code); 
    decimal GetFree(string code); 
} 

public interface IRecordImport<T> where T : IRecordBase 
{ 
    void CreateItem<T>(); 
} 
+0

在'IStockImport'聲明中缺少''。 –

+0

這與他的界面聲明tho'不同,因爲理想情況下,您需要在其中存在T:IStockItem',在這種情況下,爲什麼還要使它完全通用? – toadflakz

+0

我完全不喜歡這個接口,因爲它的名字中有'Stock',它與特定的記錄類有關,並且不是通用的。我會重新做一點 – Herm

1

,你可以,但它可能沒有必要。基於方法的類的接口最適用於希望與實現相關的多態性的地方。

就你而言,你想要的是能夠共享通用功能(基於IStockExport接口),但也提供了多態創建機制(基於IStockImport)。

我建議你實現一個抽象基類IStockExport它可以爲所有不同類型的IStockItem繼承(由於共用接口),然後派生類應實現IStockExport每個Create<IStockItem>()實施將是不同的,但可以由於常見行爲而以相同方式使用(總是返回IStockItem對象)。