2017-08-10 14 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を動作させる必要があります(少なくとも設計上の意味で)。おそらくNull Objectパターンを使用して、キャッシングのオンとオフをサポートすることができます。テストが重要な考慮事項である場合、この場合、何らかのテストダブルを使用するか、リポジトリとデータキャッシュを一緒にテストする必要があります。

2番目のオプションは基本的にDecoratorパターンです(MyRepositoryにIDataCacheは必要ありません - これはコピー貼り付けによるものと思われます)。リポジトリは、キャッシングロジックを完全に無視します。キャッシュを動的に追加および削除する可能性があります。また、他の種類のデコレータでリポジトリを拡張することもできます(たとえば、ログを追加するなど)。テストに関しては、テストを二重にすることなくそのままリポジトリをテストすることができます。

+0

解決方法#1 - キャッシングをオンまたはオフにする必要はないと仮定しましょう。 解決策#2 - IDataCacheが抽象化された理由は、単体テストではなく、CachedRepository/Repositoryのインスタンスを一時的/スコープにすることができるように、単体テストを可能にすることです。 –

関連する問題