Место попробовать/поймать в бизнес-логики и пользовательского интерфейса


Я нашел следующие два типа обработки исключений в слой бизнес-логики.

ASP.NET 3.5 корпоративных приложений разработка использует подобный метод, как и первый (я его читал несколько лет назад).

Я также нашел это на переполнение стека, но это не ответ на мой вопрос.

Мне интересно, какой лучше дизайн и эффективность.

Способ 1 - в слой бизнес-логики

private int InsertUser(string firstname, string lastname, ref List<string> errors)
{
    if (!string.IsNullOrEmpty(firstname))
        errors.Add("First name is required.");

    if (!string.IsNullOrEmpty(lastname))
        errors.Add("Last name is required.");

    if (errors.Count > 0)
        return -1;

    int userId = -1;

    try
    {
        // Insert user and return userId    
    }
    catch (Exception ex)
    {
        // Log error to database
        errors.Add("Error occurs. Please contact customer service.");
    }

    return userId;
}

Способ 2 - в слой бизнес-логики

private int InsertUser(string firstname, string lastname)
{
    if (!string.IsNullOrEmpty(firstname))
        throw new ArgumentNullException(firstname);

    if (!string.IsNullOrEmpty(lastname))
        throw new ArgumentNullException(lastname);

    int userId = -1;

    // Insert user and return userId. Let user handle the exception in UI.

    return userId;
}

Недостатком метода 2 заключается в том, что пользовательский интерфейс должен отфильтровать данные для отображения/не отображения ошибки в зависимости от исключения. Например, вы можете не отображать система.Данных.Сущность исключения пользователей.



10536
6
задан 29 июля 2011 в 07:07 Источник Поделиться
Комментарии
6 ответов

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

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

try {
// Insert user and return userId...
} catch (Exception ex) {
// Log error to database...
throw; // Relay error to UI layer.
}

8
ответ дан 29 июля 2011 в 07:07 Источник Поделиться

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

Так как, похоже, все, что вы собираетесь делать с ошибкой в журнале, я бы использовал метод 2 в этом конкретном случае.

3
ответ дан 29 июля 2011 в 07:07 Источник Поделиться

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

class User
{
[Required]
public string FirstName { get; set; }

[Required]
public string LastName { get; set; }
}

static class Validator
{
public static List<string> Validate(object objectToValidate)
{
List<string> result = new List<string>();
//Get all properties with "Required" attribute
//For each property
//If this property is empty
//Add to result
//Return result
}
}

Затем, ваш код пользовательского интерфейса будет как:

var validationErrors = Validator.Validate(user);
if (validationErrors.Count == 0)
{
UsersService.Insert(user);
}
else
{
private DisplayErrors(validationErrors );
}

И UsersService.Вставить код:

var validationErrors = Validator.Validate(user);
if (validationErrors.Count == 0)
{
Repository.Insert(user);
}
else
{
throw new Exception("Some details about validation errors.");
}

Конечно, это очень упрощенный пример, и есть сотни вариантов, но идея в том, чтобы отделить проверки и обработки ошибок.

3
ответ дан 1 августа 2011 в 12:08 Источник Поделиться

Это может быть больше работы для кого-то, используя способ 1, чтобы поймать ошибки, нуль аргументов. Также, если они не могут видеть ваш код, то это будет прямо-таки занозой в заднице. Кроме этого, это ваш выбор. Как правило, люди просто поместите вещи в попытке поймать и ожидать lib для исключения. Я не рекомендую иметь два способа создания отчетов об ошибках.

0
ответ дан 29 июля 2011 в 07:07 Источник Поделиться

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

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

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

0
ответ дан 29 июля 2011 в 07:07 Источник Поделиться

Событие хотя попробовать/поймать медленнее, я предпочел бы, по следующим причинам.


  • Через Если/список метод требует, чтобы каждый метод, который называю это
    метод проверки на наличие ошибок, не только это, но это требует все
    не забудьте проверить на наличие ошибок, и если кто-то забыл, то они будут
    есть ошибки

  • Вы можете иметь обработчик исключений уровне
    запишите все исключения из хранилища

  • Вы можете поймать все исключения в одном месте (службы WCF, приложения), так меньше кода
    необходимых для рассмотрения индивидуальных ошибок.

  • Гораздо проще на вызывающей стороне для осуществления звонка просто обернуть вызов в try и Catch. Более читабельный код.

0
ответ дан 29 июля 2011 в 07:07 Источник Поделиться