2017-08-10 64 views
0

實現數據庫級緩存的正確方法是什麼? (這不是緩存提供商,它是關於緩存和存儲庫之間的關係!)如何正確實現數據庫級緩存

解決方案#1:注入外部簡單緩存

public class MyRepository : IMyRepository 
{ 
    private readonly IDataCache _dataCache; 

    public MyRepository(IDataCache dataCache) 
    { 
     _dataCache = dataCache; 
    } 

    public string Get(int id) 
    { 
     var result = _dataCache.Get(id) as string; 

     if (result == null) 
     { 
      //Go fetch data from data source 
      _dataCache.Add(id, result); 
     } 

     return result; 
    } 
} 

解決方案#2:其它CachedRepository類實現相同的接口 (這將需要一些時髦的DI配置正確解決,但它是可能的)

public class MyRepository : IMyRepository 
{ 
    private readonly IDataCache _dataCache; 

    public MyRepository(IDataCache dataCache) 
    { 
     _dataCache = dataCache; 
    } 

    public string Get(int id) 
    { 
     //Go fetch data from data source 
     return result; 
    } 
} 

public class CachedMyRepository : IMyRepository 
{ 
    private readonly IMyRepository _myRepository; 
    private readonly IDataCache _dataCache; 

    public CachedMyRepository(IMyRepository myRepository, IDataCache dataCache) 
    { 
     _dataCache = dataCache; 
     _myRepository = myRepository; 
    } 

    public string Get(int id) 
    { 
     var result = _dataCache.Get(id) as string; 

     if (result == null) 
     { 
      result = _myRepository.Get(id); 
      _dataCache.Add(id, result); 
     } 

     return result; 
    } 
} 

(每種解決方案都基於這個簡單的存儲庫和高速緩存接口爲了討論)

public interface IMyRepository 
{ 
    string Get(int id); 
} 

public interface IDataCache 
{ 
    object Get(object key); 
    void Add(object key, object item); 
} 
+0

你緩存一些永遠不會改變其狀態的對象嗎?你什麼時候使緩存無效?從IDataCache接口看來,我從來沒有喜歡過我。 –

+0

Mc Kevin。你錯過了這一點。這不是關於緩存實現,這是關於存儲庫和緩存之間的關係。請閱讀該問題。 –

+0

解決方案2對我來說更好,我認爲您在解決方案2的MyRepository中不需要IDataCache。 –

回答

0

那麼,我不會說這裏有嚴格的「正確」方式。你必須考慮每個設計的含義,看看哪些更適合你的特定場景。

第一個選項使您的存儲庫在概念上成爲一個緩存存儲庫,因爲它需要一個IDataCache才能工作(至少,這就是設計所暗示的)。您可以使用空對象模式來支持打開和關閉緩存。如果測試對你來說是一個重要的考慮因素,那麼在這種情況下,你需要使用某種測試加倍,或者你可以一起測試版本庫和數據緩存。

第二個選項基本上是裝飾模式(除了你不需要IDataCache到MyRepository中 - 我認爲這是由於複製粘貼)。它使您的存儲庫完全無視任何緩存邏輯。可以動態添加和刪除緩存,還可以使用其他類型的修飾器來擴充您的存儲庫(例如,您可以添加日誌記錄)。至於測試 - 您可以按原樣測試您的存儲庫,而無需進行任何測試。

+0

解決方案#1 - 讓我們假設沒有要求打開或關閉緩存,它只是一直開着。 解決方案#2 - IDataCache被抽象化的原因是爲了讓單元測試它而不暴露一堆東西,並且允許CachedRepository/Repository的實例是transient/scoped而不是singleton。 –