Должен ли бизнес-уровень приложения иметь доступ к объекту сеанса?

StackOverflow https://stackoverflow.com/questions/927448

  •  06-09-2019
  •  | 
  •  

Вопрос

Допустим, у вас есть 3 слоя:Пользовательский интерфейс, Бизнес, Данные.

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

Я использую c # 2.0 .net

Это было полезно?

Решение

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

Что я бы сделал, так это для всех данных, которые являются состоянием сеанса, я бы создал класс для инкапсуляции извлечения этих данных.Это позволит внести изменения в будущем.

Редактировать:Пользовательский интерфейс следует использовать только для выполнения следующих действий:1.Вызовите бизнес-уровень.2.Взаимодействие с пользователем (сообщения и события).3.Манипулируйте визуальным объектом на экране.

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

Другие советы

Нет.Если у вас был уровень "Контроллер", вы должны получить к нему доступ там.Получите все, что вам нужно, из Сеанса и передайте это своему бизнес-уровню.

Вздох.

Широкий консенсус будет отрицательным;бизнес-уровень и контроллер / веб-уровень должны поддерживаться по-разному, поскольку это отдельные задачи.

Дело в том, что вы, кажется, называете это "чистота противреальность" - вопрос, который невероятно недальновиден и слегка неприятен.Это также противоречит смыслу задавать этот вопрос;если вы не собираетесь учитывать представленные мнения, тогда зачем запрашивать их?

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

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

До этого момента весь пользовательский интерфейс был несущественным;не имеет значения, вводит ли пользователь, скажем, данные клиента в приложении командной строки или перемещается по какой-либо многостраничной веб-форме с данными, сохраненными в сеансе.Допустим, вы выберете последнее;прикрепите к нему веб-интерфейс.Теперь то, что вас интересует, - это написание относительно простого кода для обработки извлечения запрошенных данных и представления их пользователю.Дело в том, что ваше веб-приложение;внешний интерфейс, это это весь ваш пользовательский интерфейс;сеансы и все такое.В тот момент, когда ты готов сказать: "Эй, давайте остановимся на том, что данные клиента в базу данных" вы идете и ссылаться на эти Ох-так-с любовью созданный сервис слоев, проходя каждый бит информации, которые веб-приложения, припрятал;введенные пользователем данные, имя пользователя, вносящего изменения;все это дерьмо.И ваш уровень обслуживания справляется с этим.Или, как вариант, суки, потому что вы забыли обязательное поле.

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

Нужно добавить новое правило проверки?Никаких проблем;сделайте так, чтобы уровень обслуживания выполнял проверку и обрабатывал проблемы пользовательского интерфейса по мере необходимости выше по цепочке.Нужно изменить способ вычисления чего-либо?Измените это на бизнес-уровне.Больше ни на что не нужно воздействовать.

По-моему, пахнет странно.Может быть, вам нужен уровень представления для управления сеансом и любой другой информацией о состоянии?

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

Я считаю ненужное использование Session запахом кода в целом, часто строки запросов, файлы cookie и viewstate имеют меньший вес и имеют лучшую "область видимости"

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

Например, в консольном приложении ASP.NET веб-приложение, служба Windows и приложение Windows Forms - только ASP.NET имеют сеанс.

Тем не менее, возможность поддержки нескольких пользовательских интерфейсов является сильно переоцененной функцией, и не требуется совершенного предвидения, чтобы оценить, будете ли вы когда-нибудь переносить свое приложение на другой пользовательский интерфейс.Если вы абсолютно уверены, что ваша логика отныне и навсегда будет выполняться только в приложении ASP.NET, тогда все в порядке.

Исключением может быть модульное тестирование.Тестовые программы NUnit представляют собой другой пользовательский интерфейс, и трудно имитировать Запрос, Ответ, сеанс, Приложение и т.д.

Если вы сохраните три перечисленных вами уровня, то "Бизнес-" уровень, скорее всего, будет наиболее подходящим для работы с объектами сеанса.

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

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

Например, в нашем приложении у нас есть база данных для каждого клиента, но одна кодовая база.Таким образом, у нас есть информация о клиенте в сеансе для каждого пользователя.Конечно, затем мы могли бы извлечь эти данные из сеанса на веб-уровне, а затем передать их на бизнес-уровень.Конечно, бизнес-уровень даже не заботится об этом, но это необходимо уровню данных для подключения к правильной базе данных.Таким образом, бизнес-уровень должен был бы передать его на уровень данных.Похоже, что множество параметров передается без каких-либо веских бизнес-причин.В нашем случае наш уровень данных проверяет объект сеанса на наличие строки подключения и запускается оттуда.Мы закодировали проблему отсутствия сеанса, если это не веб-приложение (и у нас есть службы Windows и вспомогательные приложения .exe) следующим образом:

protected virtual string GetConnectionString()
{
string connectionString;
string connectionStringSource;

//In app.config?
if (ConfigurationManager.AppSettings[_ConnectionStringName] != null &&
   ConfigurationManager.AppSettings[_ConnectionStringName] != "")
{
   connectionString = ConfigurationManager.AppSettings[_ConnectionStringName];
   connectionStringSource = "Config settings";
}
//Nope? Check Session
else if (null != HttpContext.Current && null != HttpContext.Current.Session &&
   null != HttpContext.Current.Session[_ConnectionStringName])
{
  connectionString = (string)HttpContext.Current.Session[_ConnectionStringName];
  connectionStringSource = "Session";
}
//Nope? Check Thread
else if (null != System.Threading.Thread.GetData(
      System.Threading.Thread.GetNamedDataSlot(_ConnectionStringName)))
{
   connectionString = (string)System.Threading.Thread.GetData(
          System.Threading.Thread.GetNamedDataSlot(_ConnectionStringName));
   connectionStringSource = "ThreadLocal";
}
else
{
   throw new ApplicationException("Can't find a connection string");
}

if (debugLogging)
   log.DebugFormat("Connection String '{0}' found in {1}", connectionString, 
          connectionStringSource);

return connectionString;
}

Доступ к сеансу с бизнес-уровня определенно пахнет кодом.

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

Например, предположим, вы хотите использовать один набор объектов для одной переменной сеанса и другой набор для другой переменной.Ваш контроллер может вызвать уровень обслуживания и передать переменную.Затем уровень обслуживания вернет соответствующий бизнес-объект.

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

Объект session привязан к конкретной реализации пользовательского интерфейса, поэтому смерть вашего бизнес-уровня для вашего сеанса - это неприятный запах.

Кроме того, у вас, вероятно, должна быть возможность модульного тестирования вашего бизнес-уровня - как вы собираетесь это делать, если есть зависимости от сеанса?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top