1

我正在用一个方法编写一个简单的小类发送电子邮件。我的目标是在旧版 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
}

任何建议将不胜感激,因此非常感谢您的所有评论!

注意:在这种特殊情况下实现企业库的验证应用程序块是否方便?

4

3 回答 3

9

考虑一下您对 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

于 2009-07-09T06:18:40.170 回答
3

连续有两个throw语句没有任何意义——只有第一个将被执行,然后控制将传递给异常处理程序,而永远不会传递给第二个throw

在我看来,仅仅说“发件人电子邮件无效”之类的就足够了。电子邮件非常简单且简短,因此用户无需任何额外指导即可解决此问题。

我也认为最好先检查所有传入的值,然后才开始工作。如果您随后遇到无效的参数值并抛出异常并且永远无法完成这项工作,那么部分工作的意义何在。尽可能早地指出错误——如果可能的话,从一开始就指出。

于 2009-07-09T05:53:22.017 回答
1

和:

采用

string.IsNullOrEmpty(subject)

而不是

subject == null

用于检查您的字符串是否为空。

于 2009-07-09T05:58:10.320 回答