Как удалить дубликаты кодов в этом дизайне? - PullRequest
1 голос
/ 02 сентября 2011

У меня около 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 (...) также отличается

Один из возможных вариантов, который я подумал, заключался в использовании 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();
    }
 }

Что вы думаете?

Спасибо

1 Ответ

0 голосов
/ 02 сентября 2011

Если бы я был вами, я бы создал абстрактный базовый класс, имеющий общий метод 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)
    {
        ...
    }

}

В базовый класс вы можете поместить все поведение, общее для всего, затем в переопределяющие методы вы можете поместить все, что специфично для конкретного типа, с которым вы имеете дело.

Вместо использования автомобилей и микроавтобусов ниже приведен пример, более специфичный для вашего кода.

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();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...