2011-09-02 18 views
1

私は約30のデータアクセスクラスを持ち、それらのすべてにいくつかのパラメータを持つGetAllメソッドが含まれています。それらのすべてでこのデザインで重複したコードを削除するにはどうすればよいですか?

私のコードは以下のようになります。

public IEnumerable<IHierarchyDivisionDailyResult> GetAll(short masterId, DateTime startDate, short gbuId) 
    { 
     var cacheKey = this.Cache.CreateCacheKey(this, masterId, startDate, gbuId); 

     var result = this.Cache.GetList<IHierarchyDivisionDailyResult>(cacheKey); 

     if (result != null) return result; 

     lock (LockObject) 
     { 
      result = this.Cache.GetList<IHierarchyDivisionDailyResult>(cacheKey); 

      if (result != null) return result; 

      using (var dataContext = OscaDataContext.CreateWithCustomTimeOut()) 
      { 
       result = dataContext.HierarchyDivisionDaily(masterId, startDate, gbuId).ToList(); 
       this.Cache.Add(cacheKey, result); 
      } 
     } 

     return result; 
    } 

私は重複コードが削除されますようにコードをリファクタリングしたいと思います。それはどのように可能でしょうか?各実装で異なる/共通している何

は以下のとおりです。

  • CreateCacheKeyは、常にすべての入力は
  • Cache.GetListパラメータを取得します - タイプが
  • 異なる可能性があるもののGETALLメソッドの戻り値の型があります各実装で異なる
  • 上記のようにすべてにロックが存在する
  • dataContextオブジェクトは常に上記のように作成されます
  • dataContext.Entity(...)もある異なる

私は、入力パラメータと出力タイプを見つけるためにリフレクションを使用することだと思った一つの可能​​なオプションは、その後、私は、コードのほとんどをマージすることができますしかし、リフレクションアプローチのパフォーマンスは、私が読んだことほど素晴らしいものではありません。

このように理想的なのは、結果が自動的にキャッシュされるように、メソッドに「キャッシュ」属性を追加できることです。



[Cache] 
public IEnumerable GetAll(short masterId, DateTime startDate, short gbuId) 
{ 
    using (var dataContext = OscaDataContext.CreateWithCustomTimeOut()) 
    { 
     return dataContext.HierarchyDivisionDaily(masterId, startDate, gbuId).ToList(); 
    } 
} 

あなたはどう思いますか?

私があなただったら、私はこのような一般的なGETALLメソッドを持つ抽象基本クラスを作成します。..

public abstract class DataAccessBase<T> where T : VehicleBase 
{ 

    public virtual T GetAll(short masterId, DateTime startDate, short gbuId) 
    { 
     ... 
    } 

} 

次にあなたがこのの具体的な実装を作成することができますおかげで、

答えて

0

..

public class CarDataAccess : DataAccessBase<Car> 
{ 

    public override Car GetAll(short masterId, DateTime startDate, short gbuId) 
    { 
     ... 
    } 

} 

public class VanDataAccess : DataAccessBase<Van> 
{ 

    public override Van GetAll(short masterId, DateTime startDate, short gbuId) 
    { 
     ... 
    } 

} 

基本クラスでは、すべてに共通するすべての動作を設定できます。次に、オーバーライドするメソッドでは、特定のあなたが扱っているタイプ。代わりに車やバンを使用しての

は、ここにあなたのコードに、より具体的な例である。..

public abstract class DataAccessBase<T> 
{ 

    public virtual IEnumerable<T> GetAll(short masterId, DateTime startDate, short gbuId) 
    { 
     var cacheKey = this.Cache.CreateCacheKey(this, masterId, startDate, gbuId); 

     List<T> result = this.Cache.GetList<T>(cacheKey); 

     if (result != null) return result; 

     lock (LockObject) 
     { 
      result = this.Cache.GetList<T>(cacheKey); 

      if (result != null) return result; 

      using (var dataContext = OscaDataContext.CreateWithCustomTimeOut()) 
      { 
       result = this.GetResult(dataContext, masterId, startDate, gbuId); 
       this.Cache.Add(cacheKey, result); 
      } 
     } 

     return result; 
    } 

    protected abstract List<T> GetResult(var dataContext, short masterId, DateTime startDate, short gbuId); 
} 


public class HierarchyDivisionDailyResultDataAccess : DataAccessBase<IHierarchyDivisionDailyResult> 
{ 

    public virtual IEnumerable<IHierarchyDivisionDailyResult> GetAll(short masterId, DateTime startDate, short gbuId) 
    { 
     return base.GetAll(masterId, startDate, gbuId); 
    } 

    protected override List<IHierarchyDivisionDailyResult> GetResult(var dataContext, short masterId, DateTime startDate, short gbuId) 
    { 
     return dataContext.HierarchyDivisionDaily(masterId, startDate, gbuId).ToList(); 
    } 
} 
+0

おかげで、私はこのアプローチを使用することはできません。各GetAllメソッドの入力パラメータは異なります。 –

+0

この場合、メソッドオーバーロードはあなたの友人です。異なるパラメータを含むオーバーロードを作成し、オーバーロード呼び出しを標準ベースメソッドにします。または、あなたは一歩踏み込んで、より高いレベルでデザインを検討する必要があるかもしれません。 GetAllパラメータがすべて異なっている場合、コードの重複を解消しようとすると、実行できない/実際的でないことをしようとしています。すべてのCRUDメソッドのパラメータが一貫している別の設計を検討してください。これにより、データレイヤのAPIがさらに向上します。 – Martyn

+0

もしパラメータが一貫していれば、私はそれをしたでしょう。この質問では、入力パラメータと出力パラメータは一貫していませんが、論理の90%は前述のとおりです。 –