2010-12-07 110 views
4

我開始設計一個小應用程序,並且有一些與架構相關的問題。C#設計問題

我有一些基本的實體,我願意模型 - RepositoryIndicator

Repository基本上是使用Repository Pattern一個門面,這是能夠使用一些數據庫持有者檢索/存儲任意實體(現在它NHibernate驅動的,但我想這實際上並不是很重要)。

Indicator可能被稱爲我的應用程序的邏輯核心。它用於合併抽象值和實現該值的確切時間(因此它形成並在Value - Time對上運行)。

我願意做這個Indicator儘可能的通用,還是我覺得我目前的解決方案是一個很大的失敗:)

請參見下面的代碼塊:

public interface IIndicator<T> 
{ 
    IEnumerable<T> RetrieveValues(DateTime start, DateTime end); 
} 

// Should also have something like indicator wrapper/proxy stub here - anything 
// that represents the 'IIndicator' interface acts through that proxy and 
// caches the evaluated data using it. 

這是實施該指標的基本嘗試(現在這實際上可以視爲模擬):

public class Indicator<TValue> : 
    // Self-referencing generic parameter. 
    IIndicator<Indicator<TValue>.TimestampProxy> 
{ 
    // Proxy, which is used to add the timestamp to 
    // every indicated value. 
    public class TimestampProxy 
    { 
     public TValue Value; 
     public DateTime Time; 

     public TimestampProxy(DateTime time, TValue value) 
     { 
      Time = time; 
      Value = value; 
     } 
    } 

    private readonly IRepository repository; 

    public Indicator(IRepository repository) 
    { 
     this.repository = repository; 
    } 

    public IEnumerable<TimestampProxy> RetrieveValues(DateTime start, DateTime end) 
    { 
     // Note the custom time stamp comparation in the lambda 
     // expression. Comparation includes the 'start' and 'end' limits. 
     IQueryable<TimestampProxy> queryable = repository.Retrieve<TimestampProxy>(
      x => x.Time.CompareTo(start) >= 0 && x.Time.CompareTo(end) <= 0); 

     return queryable.ToList(); 
    } 
} 

現在 - 這可能看起來很好,但我絕對相信所使用的TimestampProxy真的是邪惡的。

這也使得很難的事情理解(例如,方法簽名IEnumerable<TimestampProxy> RetrieveValues(...)可能會導致「WTF?!」短語來自誰檢查代碼的人)。

不幸的是,我不能拿出一個更好的解決方案/全球重新設計 - 你能指點我怎麼做,或乾脆告訴怎麼樣的特點應該做的一些想法?

謝謝。

回答

1

將RetrieveValues方法重構回Repository本身,並使用基本上替代TimestampProxy類的更簡單的Indicator類。

public class Indicator<T> 
{ 
    public DateTime Timestamp { get; set; } 
    public T Value { get; set; } 
} 


public class Repository 
{ 

    public IEnumerable<Indicator<T>> RetrieveIndicators<T>(DateTime start, DateTime end) 
    { 
      // determine table to query based on type T 
      // query and convert objects to Indicator<T> 
      // return collection 
    } 
} 

困擾我的一件事是,使它成爲通用的,你已經失去了與數據庫表的連接。最好簡單地定義一個接口,使所有特定的DB對象都實現並使用部分實現將實際的「值」映射到Value屬性上。

public interface Indicator<T> 
{ 
    DateTime Timestamp { get; } 
    T Value { get; } 
} 

public partial class TemperatureIndicator : Indicator<double> 
{ 
    public double Value { get { return this.Temperature; } } 
} 

現在有你的資料庫實現返回每種類型的對象的方法 - 這可以作爲(在.NET 4或轉換爲較低的版本)共同操作的接口類型的對象。