Обработка исключений: насколько детализирован вы, когда дело доходит до проверки аргументов? - PullRequest
1 голос
/ 09 июля 2009

Я пишу простой маленький класс с помощью одного метода отправки электронной почты. Моя цель - реализовать его в унаследованном проекте Visual Basic 6, представив его как объект COM с помощью средства взаимодействия COM.

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

public class MyMailerClass
{
    #region Creation
    public void SendMail(string from, string subject, string to, string body)
    {
        if (this.IsValidMessage(from, subject, to, body)) // CS1501
        {
            MailMessage msg = new MailMessage();
            msg.IsBodyHtml = true;
            msg.From = new MailAddress(from);
            msg.To.Add(to);
            msg.Subject = subject;
            msg.Body = body;
            SmtpClient srv = new SmtpClient("SOME-SMTP-HOST.COM");
            srv.Send(msg);
        }
        else
        {
            throw new ApplicationException("Invalid message format.");
        }
    }
    #endregion Creation

    #region Validation
    private bool IsValidMessage(string from, string subject, string to, string body)
    {
        Regex chk = new Regex(@"(\w+@[a-zA-Z_]+?\.[a-zA-Z]{2,6})");
        if (!chk.IsMatch(from))
        {
            return false;
        }
        if (!chk.IsMatch(to))
        {
            return false;
        }
        if (!string.IsNullOrEmpty(subject))
        {
            return false;
        }
        if (!string.IsNullOrEmpty(body))
        {
            return false;
        }
        else
        {
            return true;
        }
    }
    #endregion Validation
}

Любое предложение будет высоко оценено, поэтому большое спасибо заранее за все ваши комментарии!

Примечание : Было бы удобно реализовать Блок приложения проверки библиотеки предприятия в данном конкретном случае?

Ответы [ 3 ]

9 голосов
/ 09 июля 2009

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

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

Вы получите несколько хороших эффектов от этого изменения:

(1) Увеличенное разделение интересов. Задача SendMail - заставить механизм электронной почты работать, а не выносить суждение о том, является ли адрес электронной почты действительным. Изолируйте это политическое решение на код, специализирующийся на проверке.

(2) Проверка адреса сама по себе является полезным инструментом; Есть много случаев, когда вы хотите узнать, правильно ли сформирован адрес, не отправляя на него почту.

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

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

Вот несколько статей на эту тему, которые я написал для вас:

Обработка исключений: http://ericlippert.com/2008/09/10/vexing-exceptions/

Методы интенсивного технического обслуживания: http://blogs.msdn.com/ericlippert/archive/2008/09/08/high-maintenance.aspx

3 голосов
/ 09 июля 2009

Наличие двух throw операторов подряд не имеет смысла - будет выполнен только первый, а затем управление будет передано обработчику исключений, а не второму throw.

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

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

1 голос
/ 09 июля 2009

И

Используйте

string.IsNullOrEmpty(subject)

вместо

subject == null

для проверки, если ваши строки пусты.

...