2013-05-12 228 views
4

我已經像一個通用接口通用接口:最佳實踐:

public interface IDatabaseElement<T> 
{ 
    IList<T> GetAll(); 
    T Get(id); 
    void Save(T element); 
    void Delete(int id); 
} 

如果我有例如僅使用上述方法的兩個要素(人員和商店)被認爲是最佳實踐?

答:製作一個新的接口的每個元素,如:

public interface IPerson : IDatabaseElement<Person> { } 
public interface IStore : IDatabaseElement<Store> { } 

,然後我的類,如:

public class Person : IPerson { .... } 
public class Store : IStore { .... } 

和instanciating變量時:

IPerson person = new Person(); 
IStore store = new Store(); 

或 乙:直接使用通用接口:

public class Person : IDatabaseElement<Person> { .... } 
public class Store : IDatabaseElement<Store> { .... } 

和instainciating當變量:

IDatabaseElement<Person> person = new Person(); 
IDatabaseElement<Store> store = new Store(); 

什麼被認爲是最佳做法?

+0

這個問題是偏離主題。 – 2013-05-12 13:03:29

+0

@olf請看看SO的常見問題,這個問題不是關於具體問題。 – Candide 2013-05-12 13:04:52

+1

爲什麼你的實體首先知道數據庫?而且你的方法對一個實體來說是完全荒謬的,他們會適合一個存儲庫。 – CodesInChaos 2013-05-12 13:06:07

回答

7

有一個已知的設計模式,您正在調用IDatabaseElement<T>;它被稱爲Repository Pattern。因此,通過重命名IDatabaseElement<T>開始:

public interface IRepository<TEntity> { ... } 

此外,由於你定義IPerson接口,好像要定義一個接口,爲Person實體,而不是倉庫。

將實體隱藏在接口後面是不好的做法,因爲實體是數據對象,接口只需要抽象行爲。

因此,不要調用接口IPerson,首先調用它IPersonRepository

在另一方面,如果你的Person類實際上包含數據(如FirstNameLastNameAge等),在這種情況下,你是混合責任。您的實體不應該知道如何從數據庫中檢索自己(或其他實例!!!)。從數據庫中檢索數據並保存數據是兩種不同的責任,你應該將它們分開(賦予每個責任它自己的類)。如果您違反Single Responsibility Principle,您的系統將很快變得無法維護。

現在,爲每個存儲庫類型(例如IPersonRepository)製作特定的接口是一個壞主意。有一個通用抽象的主要原因是因爲這使得添加額外的行爲(如橫切關注)更容易,因爲這允許您定義一個通用裝飾器,例如:AuditTrailingRepositoryDecorator<T>。但是當你讓你的人存儲庫實現繼承自IPersonRepository時,你不能用泛型裝飾器來包裝它,只是因爲你在IPersonRepository上定義的所有方法本身都不會被訪問。這也使得編寫單元測試變得更加容易,因爲在你的測試套件中,你只需要創建一個IRepository<T>的單個通用僞造實現。

如果您對添加橫切關注點和輕鬆測試代碼庫的能力不感興趣,可以使用特定(非通用)接口,如IPersonRepositoryIStoreRepository