2010-01-20 45 views
2

我試圖更好地堅持Single Responsibility Principle,並且我遇到了如何構建與數據庫通信的常規類設計的問題。在一個簡化的版本,我基本上具有含有一個數據庫:在遵循單一責任原則的同時設計數據庫交互

廠商< ==探頭< ==> ProbeSettings

探針具有製造商。探針有一組設置。相關的對象可以在整個應用程序中訪問,坦率地說,目前的實現是一團糟。

目前,這裏有一個如何溝通和對象實現了一個普遍觀點:

public class Manufacturer 
{ 
    public int ID; // Primary key, auto-incrementing on insert 
    public string Name; 
} 

public class Probe 
{ 
    public int ID; // Primary key, auto-incrementing on insert 
    public int ManufacturerID; 
    public string Name; 
    public int Elements; 
} 

public class ProbeSettings 
{ 
    public int ProbeID; // Primary key, since it is unique. 
    public int RandomSetting; 
} 

// This class is a mess... 
public static class Database 
{ 
    public static string ConnectionString; 

    public static void InsertManufacturer(Manufacturer manuf); // ID would be ignored here, since it's auto-incrementing. 
    public static void InsertProbe(Probe probe); // Again, ID generally ignored. 
    public static void InsertProbeSettings(ProbeSettings probeSet); 

    public static Manufacturer[] GetAllManufacturer(); 
    public static Probe[] GetProbesFromManufacturer(int manufacturerID); 
    public static Probe[] GetProbesFromManufacturer(Manufacturer manuf); 
} 

我在這裏看到的許多問題。

  1. Database確實太多了。
  2. 這些對象在讀取時可能是不可變的,唯一的問題是插入後,我不知道它們分配了什麼ID,插入的對象現在已經過時。
  3. 任何時候一個類需要從Database獲取信息,我不得不添加另一個Get方法來處理特定的查詢。

在這裏,我真的很遺憾什麼是正確的實現。改進我唯一真正的想法是某種基本接口的數據庫對象,儘管它可能只是幫助插入...

public interface IDatabaseObject 
{ 
    void Insert(Database db); 
    bool Delete(Database db); 
} 

的是,真正實現這個好辦法?

+0

如果您發現存儲庫的「最佳」解決方案,讓我們都知道。因爲我曾經使用過的解決方案沒有在邊緣周圍出現某種粗俗的廢話。 – Will 2010-01-20 21:39:05

回答

4

很好用DB工作,同時保持SRP(或任何其他種類的理智型的)最好的解決辦法是使用某種ORM(例如,NHibernate的)。

這將允許您按照原樣處理類,而不是手動將它們從/傳送到數據庫。

例如,NH你的類可以是這樣的:

public class Manufacturer 
{ 
    public string Name { ... } 
    public IList<Probe> Probes { ... } 
} 

public class Probe 
{ 
    public string Name { ... } 
    public int Elements { ... } 
    public ProbeSettings Settings { ... } 
} 

public class ProbeSettings 
{ 
    public int RandomSetting; 
} 

正如你看到的,你已經不需要GetProbesFromManufacturer因爲你可以製造商中導航集合。

此外,ORM將管理對象ID併爲您節省。因此,您所需要的只是一小部分固定數量的常規方法,如LoadById/LoadAll,它們很適合於一個類數據訪問的SRP類。此外,您可能需要爲每個複雜且可配置的數據庫查詢分配一個類。

+0

最近幾個月我一直在使用Fluent NHibernate Automapping,並且可以確認所有這些都是真實的。我喜歡能夠在C#(包括LINQ)中完成所有任務,並且(主要)不必擔心底層關係模型。 – 2010-01-20 21:58:01

+0

使用ORM是我錯過的,這是正確的。無論是NHibernate還是DBLinq for MySQL,都可以完成這項工作。謝謝。 – 2010-01-21 21:04:59

2

這聽起來像您正在尋找ORM。由於您使用的是C#,因此我假定您可以訪問LinqToSQL作爲.NET框架的一部分。只要管理基本的CRUD操作,Linq就可以做你正在尋找的東西。類似的項目,也值得一試,是Castle ActiveRecordNHibernate.

+0

我使用MySQL,但http://code.google.com/p/dblinq2007/可能是LinqToSQL的解決方案。看看它,謝謝。 – 2010-01-20 21:35:34