Должен ли бизнес-уровень приложения иметь доступ к объекту Session? - PullRequest
7 голосов
/ 29 мая 2009

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

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

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

Ответы [ 10 ]

5 голосов
/ 30 мая 2009

Вздох.

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

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

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

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

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

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

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

5 голосов
/ 29 мая 2009

Нет. Если у вас был слой «Контроллер», вы должны получить к нему доступ. Получите с сессии то, что вам нужно, и передайте ее на уровень вашего бизнеса.

3 голосов
/ 29 мая 2009

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

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

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

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

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

3 голосов
/ 29 мая 2009

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

3 голосов
/ 29 мая 2009

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

1 голос
/ 29 мая 2009

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

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

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

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

0 голосов
/ 30 мая 2009

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

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

0 голосов
/ 30 мая 2009

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

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

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

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

0 голосов
/ 29 мая 2009

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

Например, в нашем приложении у нас есть база данных для каждого клиента, но одна кодовая база. Таким образом, у нас есть информация о клиенте в сеансе для каждого пользователя. Конечно, мы могли бы затем извлечь эти данные из сеанса на веб-уровне и затем передать их на бизнес-уровень. Конечно, бизнес-уровень даже не заботится об этом, но он нужен уровню данных для подключения к правильной базе данных. Тогда бизнес-уровень должен будет передать его на уровень данных. Похоже, много передачи параметров без уважительной деловой причины. В нашем случае наш уровень данных проверяет объект сеанса на наличие строки подключения и запускается оттуда. Мы решили проблему отсутствия сессии, если это не веб-приложение (и у нас есть службы 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;
}
0 голосов
/ 29 мая 2009

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

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

...