0

我有一个负责发送电子邮件的对象,所以我创建了一个EmailSender,然后告诉它SendEmail,传入一些EmailDetails

string diagnostics;    

EmailSender sender = new EmailSender();
try
{
    sender.SendEmail(details);
    //sender.SendEmail(details, out diagnostics);
}
catch(Exception e)
{
    logger.log(sender.CurrentError);
}

diagnostics = sender.Diagnostics;

如果我向 中添加一个 out 参数SendEmail,这是否会增加 SOLID 设计原则方面的业务责任,因为我现在说:“您必须尝试发送电子邮件,并且您还负责初始化和填充诊断数据”

也许责任不是正确的词,但是一种模式比另一种更好吗?

4

3 回答 3

2

您没有违反单一职责原则 - SRP 并不意味着对象不应该知道如何与其合作者交谈。这是其合同的一部分,这是一种自然的责任。如果EmailSender不负责报告有关邮件传递的诊断,谁会负责?

您唯一需要确保的是Diagnostics保持在与EmailSender. EmailSender不依赖于它的消费者,消费者依赖于EmailSender,所以EmailSender不应该采用消费者的形式主义,而是将自己的语义强加于他们。

于 2012-11-30T10:04:49.823 回答
1

您没有违反任何 SOLID 原则,而是违反了所谓的Samurai 原则

每个操作都应该完成他们的合同并返回一个有效的结果,或者抛出一个异常。

如果您想提供一些有关失败的附加诊断信息,而不是添加自定义异常。如果您与客户之间的合同中包含某些内容,则可以通过输出参数返回此信息。

于 2012-11-29T21:17:21.280 回答
0

查看您的代码示例,我想知道 AOP 设计是否合适。您可以使用 Policy Injection 来包装对您的 EmailSender(和其他组件)的调用。

您使用 Policy Injection 注入调用的包装器可以负责捕获和记录抛出的异常,因此此代码调用SendEmail不必执行此操作。

包装器还可以负责监控时间、写入跟踪信息等。我只是在推测,但也许这类信息与您使用Diagnostics属性的目的一致。

这样,调用者不必负责处理/记录异常,也不必负责处理诊断信息。此外,EmailSender 不必负责监控自己的性能或通过Diagnostics属性公开该信息。

此外,该CurrentError属性似乎很奇怪。CurrentError您已经在捕获异常,因此捕获包含属性具有的任何信息的特定类型的异常似乎更合适。

于 2012-11-29T21:28:34.233 回答