I see a recurring pattern in the code base I work with which involves caching. We first attempt to fetch the object from the cache. If it doesn't exist, then we make a db call to fetch it and then set it in the cache.
The code for it looks like so
var cacheKey = focus.ToString() + gridType + asCsv;
rows = MemCache.Get<QueryResultRows>(cacheKey);
if (rows == null)
{
rows = repo.GetQueryResultFor(gridType, focus);
MemCache.Set(cacheKey, rows);
}
A lot of it seems like boilerplate code to me. It is possible to collapse them into a single method that takes the 'get-from-db' method as a parameter and execute it if needed. Something along the lines of
var cacheKey = focus.ToString() + gridType + asCsv;
rows = MemCache.GetAndSetIfNeeded<QueryResultRows>(
() => cacheKey, repo.GetQueryResultFor(gridType, focus));
// MemCache code
GetAndSetIfNeeded<T>(string cacheKey, Func<T> fetchFunction)
{
var data = MemCache.Get<T>(cacheKey);
if (data == null)
{
data = fetchFunction.Invoke();
MemCache.Set(cacheKey, data);
}
return data;
}
There are two ways to look at it -
- This is a violation of Single Responsibility Principle so don't do it.
- It helps avoid boilerplate code everywhere we need caching related code
Wanted to seek the community's input on the approach.
Aucun commentaire:
Enregistrer un commentaire