2009-09-29 50 views
2

我正在創建一個示例應用程序,以便共同瞭解存儲庫和工廠方法模式,因爲它們將用於更大的項目中。如何使用存儲庫模式和工廠方法模式來組織我的類/接口?

我想達到的目標是能夠使不同的ORM工具的網站工作。

例如,網站將有LINQ to SQL和Ado實體框架工作類,然後使用工廠方法將使用這些ORM之一「使用配置值」來加載數據庫對象中的數據。

我得到了什麼到現在是像下面

interface IRepository : IDisposable 
{ 
    IQueryable GetAll(); 
} 

interface ICustomer : IRepository 
{ 
} 

public class CustomerLINQRepository : ICustomer 
{ 
    public IQueryable GetAll() 
    { 
     // get all implementation using linqToSql 
    } 
    public void Dispose() 
    { 
     throw; 
    } 
    public IRepository GetObject() 
    { 
     return this; 
    } 
} 


public class CustomerADORepository : ICustomer 
{ 
    public IQueryable GetAll() 
    { 
     // get all implementation using ADO 
    } 
    public void Dispose() 
    { 
     throw new NotImplementedException(); 
    } 
    public IRepository GetObject() 
    { 
     return this; 
    } 
} 


// Filling a grid with data in a page 
IRepository customers = GetCustomerObject(); 
this.GridView1.DataSource = customers.GetAll(); 
this.GridView1.DataBind(); 
//// 

public IRepository GetCustomerObject() 
{ 
    return new CustomerLINQRepository(); // this will return object based on a config value later 
} 

但我能感覺到有很多的設計錯誤希望你能幫助我找到答案,以獲得更好的設計。

+0

我將它重命名爲「GetCustomerObject」,它應該檢查一個配置值並根據此值返回「CustomerLinqRepository」對象或「CustomerAdoRepository」對象,因此「GetCustomerObject」是Factory方法的創建者函數 – 2009-09-29 03:40:08

回答

4

我的兩分錢:

答:我想補充通用基repository類。無論類型是什麼,許多存儲庫操作都是相同的。它可以爲您節省大量的打字。

B.我不明白爲什麼你的倉庫正在實施ICustomer接口。 您的數據對象的接口是一種很好的做法,但我認爲您的存儲庫不應該實現它。

C.如果有一個共同實現你的數據對象,我會爲他們創造一個基類和限制庫只與類型的派生類的工作。

我會做這樣的事情:

public interface IEntity 
{ 
    // Common to all Data Objects 
} 

public interface ICustomer : IEntity 
{ 
    // Specific data for a customer 
} 


public interface IRepository<T, TID> : IDisposable where T : IEntity 
{ 
    T Get(TID key); 
    IList<T> GetAll(); 
    void Save (T entity); 
    T Update (T entity); 

    // Common data will be added here 
} 

public class Repository<T, TID> : IRepository<T, TID> 
{ 
    // Implementation of the generic repository 
} 

public interface ICustomerRepository 
{ 
    // Specific operations for the customers repository 
} 

public class CustomerRepository : Repository<ICustomer, int>, ICustomerRepository 
{ 
    // Implementation of the specific customers repository 
} 

用法:

CustomerRepository repository = new CustomerRepository(); 
IList<ICustomer> customers = repository.GetAll(); 
// Do whatever you want with the list of customers 

這是我實現我的DAL使用NHibernate的方式。你可以在「NHibernate in Action」中找到一些用法。

我也推薦使用某種IoC控制器,正如Matt所建議的那樣。

+0

不錯,你能告訴我示例代碼,以獲取客戶的數據「獲取客戶的集合」,我在我的設計中寫到這樣的IRepository customers = GetCustomerObject(); this.GridView1.DataSource = customers.GetAll(); this.GridView1.DataBind(); 現在該怎麼寫呢? – 2009-09-29 12:53:31

+1

@Amr ElGarthy:我更新了答案,以顯示這兩條線一些使用 – 2009-09-29 14:56:31

+0

:1-公共類資源庫:IRepository 2-公共類CustomerRepository:庫,ICustomerRepository 它給我這個錯誤:使用泛型類型'TestApplication1.IRepository '需要'2'類型參數\t你能幫我解決嗎? – 2009-09-29 22:00:05

1

我不知道對GetWanted命名。你想得到什麼?該名稱應該更具描述性,也許GetCustomerRepository

GetCustomerObject一樣GetWanted

什麼是throw呢?

+0

我重命名它將GetCustomerObject – 2009-09-29 03:40:58

+0

更改爲拋出以及「throw new NotImplementedException();」 – 2009-09-29 03:43:31

+0

看起來不錯... – 2009-09-29 03:45:02

1

大部分看起來不錯。我有兩條評論:

  1. 我不會打電話給你的客戶倉庫ICustomer。我會稱之爲ICustomerRepository。這更直接,並闡明瞭基於知識庫的界面責任。 ICustomer聽起來像一個DataObject封裝客戶數據。
  2. 研究使用IOC容器(谷歌結構圖,城堡windsor或統一)而不是使用工廠方法。您可能會遇到很多可能導致混淆的工廠方法。相反,在您的代碼中放置一個地方可能會更清潔,您的IOC將所有存儲庫連接起來。