我正在编写一个简单的小班,用一种方法发送电子邮件。我的目标是在遗留的Visual Basic 6项目中实现它,通过COM Interop工具将其公开为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
}
任何建议都会非常感谢,所以非常感谢提前发表所有意见!
注意:在这种特殊情况下实施企业库的Validation Application Block是否方便?
答案 0 :(得分: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
答案 1 :(得分:3)
连续两个throw
语句没有任何意义 - 只有第一个语句将被执行,然后控制权将被传递给异常处理程序,而不会传递给第二个throw
。
在我看来,仅仅说“发件人电子邮件无效”就足够了。电子邮件非常简单,因此用户无需任何额外指导即可解决此问题。
我还认为最好首先检查所有传入的值,然后才开始工作。如果您可以遇到无效的参数值并抛出异常并且永远不会完成此工作,那么部分工作的重点是什么。尝试尽可能早地指出错误 - 如果可能的话,尽可能初步。
答案 2 :(得分:1)
和
使用
string.IsNullOrEmpty(subject)
而不是
subject == null
用于检查字符串是否为空。