Удаление связи уровня доступа к данным из пользовательского интерфейса

В настоящее время уровень пользовательского интерфейса моего приложения связан с моей библиотекой DAL. Dal инициализируется так:

//Initialize Data Access for AS400
Dal = JDE8Dal.Instance;
Dal.conString = Properties.Settings.Default.conAS400;

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

DAL:

public class JDE8Dal
    {
        public string conString { get; set; }
        private static readonly JDE8Dal _instance = new JDE8Dal();
        private JDE8Dal()
        {
        }
        public static JDE8Dal Instance
        {
            get { return _instance; }
        }
        // Methods
    }

Мой BLL будет выглядеть примерно так:

namespace YLA.Barcode
{
    public static class YlaBarcodeUtil
    {
        public static string LotStripZeroes(string str)
        {
            var ret = str;
            if (str.Trim().StartsWith("00"))
            {
                ret = YlaGeneralUtilities.StripLeadingNumofChars(str, 2);
            }
            return ret;
        }
    }

public class BarcodeBLL
{
    //DAL INIT HERE?
}
}

Теперь, когда мне нужно создать больше приложений, мне нужно перейти на трехуровневую архитектуру и начать читать DDD.

1) Как переместить обработку DAL в BLL? Просто добавить инициализацию в моем разделе BLL?

2) Должен ли я сохранить свой дизайн DAL как синглтон или нет?

3 ответа

Решение

Вы должны использовать шаблон Inversion of Control, чтобы уменьшить зависимость между вашими слоями. В вашем случае я бы использовал внедрение конструктора, поскольку ваш класс требует контекст данных:

public class BarcodeBLL
{
    private JDE8Dal _context;

    public BarcodeBLL(JDE8Dal context)
    {
        _context = context;
    }
}

Контекст данных должен быть недолговечными объектами. Если вы разрабатываете веб-приложение, вы должны создавать один контекст данных для каждого запроса. Я также рекомендовал бы использовать ORM (Entity Framework / NHibernate).

1: Обычно у вас есть инфраструктурный слой, который создает композицию.

2: НЕТ ВСЕМИ СРЕДСТВАМИ. Это граничит с "изучением программирования". Используйте контейнер МОК.

//Initialize Data Access for AS400
Dal = JDE8Dal.Instance;
Dal.conString = Properties.Settings.Default.conAS400;

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

public class JDE8Dal
    {
        public string conString { get; set; }
        private static readonly JDE8Dal _instance = new JDE8Dal();
        private JDE8Dal()
        {
        }
        public static JDE8Dal Instance
        {
            get { return _instance; }
        }
        // Methods
    }

Слои обычно не определяются таким образом, DAL - это сборка / dll, а не класс. Когда вы это пишете, кажется, что вам нужен объект Бога, в котором определена вся логика постоянства. Классы на уровне доступа к данным гораздо более детализированы и специализированы: например, репозитории / DAO управляют сохранением одного конкретного объекта домена.

Кроме того, обычно не стоит прибегать к синглтону "просто потому, что он чувствует себя правильно, если у него только один экземпляр". И особенно не изменчивый синглтон. В вашем примере каждый может изменить Dal.Instance.conStringс потенциально драматическими последствиями для других потребителей синглтона. Среди других недостатков.

Даже если есть вероятность, что когда-нибудь будет одна реализация вашего DAL (как AS400), в проектах разумной сложности рекомендуется использовать внедрение зависимостей для целей модульного тестирования. DI позволяет вам легко заменить ваши конкретные реализации объекта DAL на поддельные объекты DAL, которые намного легче и полезнее в модульных тестах.

public class BarcodeBLL
{
    //DAL INIT HERE?
}

Не, нет инициализации DAL здесь;)

Уровень бизнес-логики (уровень домена в DDD) не должен иметь ссылку на DAL, DAL должен иметь ссылку на BLL. Доменный объект не должен знать, как сохранить себя (принцип невосприимчивости к постоянству), потому что у него будет слишком много обязанностей (принцип единой ответственности), и это создаст тесную связь между BLL и DAL, что делает его очень неудобным для повторного использования и обслуживания BLL.

Другие вопросы по тегам