如何在此设计中删除重复代码



我有大约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总是获取所有输入参数
  • 缓存。GetList -虽然类型可以不同
  • GetAll方法的返回类型在每个实现中都是不同的
  • 锁存在于所有这些
  • dataContext对象总是如上所述创建的
  • dataContext.Entity(…)也是不同的

我认为一个可能的选择是使用Reflection来找出输入参数和输出类型,然后我将能够合并大部分代码,但是我读过的Reflection方法的性能不会很好。

最理想的是能够在方法中添加一个"Cache"属性,这样结果就会自动缓存!


[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)
    {
        ...
    }
}

然后你可以创建这个的具体实现…

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)
    {
        ...
    }
}

在基类中,你可以放置所有东西的通用行为,然后在重写方法中,你可以放置任何特定于你正在处理的特定类型的东西。

不使用Cars和Vans,这里有一个更具体到你的代码的例子…

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();
    }
}

相关内容

  • 没有找到相关文章