开发者

How to Remove Duplicated Codes in This Design?

开发者 https://www.devze.com 2023-04-01 07:14 出处:网络
I have about 30 data access classes and all of them contain a GetAll method with some parameters. My code in all of them looks like below:

I have about 30 data access classes and all of them contain a GetAll method with some parameters.

My code in all of them looks like below:

public IEnumerable<IHierarchyDivisionDailyResult> GetAll(short masterId, DateTime startDate, short gbuId)
    {
        var cacheKey = this.Cache.CreateCacheKey(this, mas开发者_如何学运维terId, 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;
    }

I'd like to refactor the code so that the duplicated codes get removed. How would that be possible?

What are common/different in each implementation are:

  • CreateCacheKey always gets all the input parameters
  • Cache.GetList - though the type could be different
  • The return type of GetAll method is different in each implementation
  • Locking exists in all of them as above
  • The dataContext object is always created as above
  • dataContext.Entity(...) is also different

One possible option I thought was to use Reflection to find out the input parameters and output type, then I'll be able to merge most of the code but the performance of the Reflection approach wouldn't be great I've read.

What would be so ideal would be to be able to add a "Cache" attribute to the method so that the result gets cached automatically!



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

What do you think?

Thanks,


If I was you, I would create an abstract base class that has a generic GetAll method like this..

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

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

}

Then you can create concrete implementations of this..

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

}

In the base class you can put all the behaviour that is common to everything, then in the overriding methods, you can put anything that is specific to the particular type that you're dealing with.

Instead of using Cars and Vans, here is an example that is more specific to your code..

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

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号