Помогите с дебатами о разделении проблем (доступ к данным и бизнес-логика)

У меня был спор с моим коллегой о том, относится ли определенная логика к уровню доступа к данным или к уровню бизнес-логики.

Сценарий таков, что BLL нужны некоторые данные для работы. Эти данные в основном хранятся в базе данных. Мы хотим кэшировать эти данные (используя System.Runtime.Caching), чтобы они были быстро доступны при последующих запросах. Архитектура такова, что DAL и BLL живут на одной коробке и в разных сборках (проекты в одном решении). Так что не стоит беспокоиться о том, что DAL может попасть по проводу или что-то в этом роде.

Мой аргумент заключается в том, что решение об использовании кеша вместо базы данных является заботой DAL. Уровень бизнес-логики не должен заботиться о том, откуда берутся данные, а только о том, что он получает нужные ему данные.

Его аргумент заключается в том, что уровень доступа к данным должен быть «чистым» и «глупым», и любая логика для принятия решения о том, чтобы поразить кэш, а не базу данных, должна быть на уровне бизнес-логики.

На мой взгляд, то, что он говорит, подрывает разделение интересов и заставляет слои быть более тесно связанными, когда цель состоит в том, чтобы сохранить слабо связанные вещи. Я вижу, где BLL мог бы захотеть контролировать это, если бы это была конкретная функция программы/интерфейса, чтобы решить, куда идти за данными, но здесь это просто не тот случай. Это очень простой сценарий кэширования, в котором база данных является основным хранилищем данных.

Мысли?


person Will.NET    schedule 25.08.2011    source источник
comment
Это, вероятно, лучше подходит для Programmers.se   -  person Jon Adams    schedule 06.02.2014


Ответы (5)


Я согласен с вами на 100%.

Кэширование является частью DAL и не относится к BLL.

В качестве примера возьмем спящий режим, он использует систему кэширования для хранения вашей сущности. Hibernate отвечает и знает, как управлять своим кешем (грязное чтение, сброс данных и т. д.).

Вы не хотите загромождать свой BLL всей этой низкоуровневой логикой данных.

С уважением

person Cygnusx1    schedule 25.08.2011

Я считаю, что кэширование должно выполняться на бизнес-уровне. В тот момент, когда вы пытаетесь получить данные из DAL, вы можете проверить, доступны ли данные в кеше system.runtime.caching, а затем использовать данные кеша, иначе извлеките данные из базы данных. Более того, если вы по какой-то причине хотите аннулировать кеш, вы можете сделать это, вызвав функцию в бизнесе позже.

person Kapil Chawla    schedule 02.02.2014

Вся цель отделения бизнес-логики от данных заключается в том, чтобы вы могли менять их по мере изменения бизнес-требований или технологий. Смешивая их, вы побеждаете эту логику, а значит, теоретически вы правы. Однако в реальном мире, я думаю, вам нужно быть немного более прагматичным. Какова реальная продолжительность жизни приложения, какова вероятность того, что технология будет меняться, и сколько дополнительной работы потребуется, чтобы четко разделить эти два понятия?

person John    schedule 25.08.2011

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

Однако, если вы намерены повторно использовать уровень данных в других проектах, или даже если нет, может быть неплохой идеей реализовать новый бизнес-уровень между существующим и уровнем данных для обработки решений о кэшировании. Потому что, в конечном счете, кэширование — это не только вопрос производительности, но и принятие бизнес-решений в отношении параллелизма и других вопросов.

Многоуровневая система — это просто то, что вы не ограничены количеством уровней, на которые вы хотите разделить вещи.

person Random    schedule 25.08.2011

Я знаю, что опоздал с игрой более чем на два года, но я хотел бы кое-что добавить:

Если у вас есть интерфейс, определенный для вашего DAL, вы можете написать механизм кэширования, который следует этому интерфейсу и управляет проблемами «кеш против источника данных», не беспокоясь об этом технологии или коде DAL, специфичном для источника, и без BLL. приходится об этом беспокоиться. Пример:

internal interface IThingsGateway 
{
    public Thing GetThing(int thingId);
    public void UpdateThing(ThingUpdateInfo info);
}

internal class MsSqlThingsGateway : IThingsGateway
{
    // implementation specific to MsSql here
}

internal class CachingThingsGateway : IThingsGateway
{
    private IThingsGateway underlyingImplementation;

    public CachingThingsGateway(IThingsGateway implementation)
    {
        this.underlyingGateway = implementation;
    }

    public Thing GetThing(int thingId)
    {
        if (this.HasCachedThing(thingId))
        {
            return this.GetCachedThing(thingId);
        }

        var thing = this.underlyingGateway.GetThing(thingId);

        this.SetCachedThing(thingId);

        return thing;
    }

    public void UpdateThing(ThingUpdateInfo info)
    {
        this.underlyingGateway.UpdateThing(info);

        this.ClearCachedThing(info.ThingId);
    }
}

И я бы использовал тот же подход, если бы мне нужно было проверить несколько источников данных на наличие чего-то: написать реализацию IThingsGateway, которая обрабатывает логику жонглирования различными источниками данных, делегируя их соответствующему... затем обернуть that< /em> в файле CachingThingsGateway. Клиентский код в конечном итоге получит ссылку IThingsGateway из какой-либо фабрики или контейнера, где будет происходить упаковка и создание экземпляра.

И все это действительно не требует особых усилий. Если вы используете кэширование, вам все равно придется писать этот код, а накладные расходы, возникающие при помещении его в другой класс с тем же интерфейсом, в худшем случае минимальны.

person tuespetre    schedule 13.11.2013