考虑一个示例,其中用户使用两个 aspx 页面中的表单输入客户对象的值。使用第一种方法,在调用构造函数之前,两个 aspx 页面都需要验证 ID 大于 0 并且 FirstName 不为空。使用第二个选项,两个页面都可以调用验证函数并向用户显示错误消息。
根据上面的例子,我更喜欢第二种选择。然而,当我在网上研究时,我不断发现它更面向对象,立即抛出异常而不让对象接受无效数据。正如我之前所说,除了例外情况,调用此构造函数的每个页面都需要验证输入是否有效。我不喜欢重复这个逻辑,所以我更喜欢第二种选择。
领域驱动设计方面的首选选项是什么?
选项1
public class Customer{
public int ID { get; set; }
public string FirstName { get; set; }
public Customer(int ID, string FirstName){
if (ID < 0)
throw new Exception("ID cannot be less than 0");
if (string.IsNullOrEmpty(FirstName))
throw new Exception("First Name cannot be empty");
this.ID = ID;
this.FirstName = FirstName;
}
}
Run Code Online (Sandbox Code Playgroud)
选项2
public class Customer{
public int ID { get; set; }
public string FirstName { get; set; }
public Customer(int ID, string FirstName){
this.ID = ID;
this.FirstName = FirstName;
}
public List<string> Validate(){
List<string> ErrorMessages = new List<string>();
if (ID < 0)
ErrorMessages.Add("ID cannot be less than 0");
if (string.IsNullOrEmpty(FirstName))
ErrorMessages.Add("First Name cannot be empty");
return ErrorMessages;
}
}
Run Code Online (Sandbox Code Playgroud)
我确信这个问题已经在其他地方得到了回答。但这里有一些其他的阅读链接:
从《实用程序员》一书中,与异常使用相关的大问题是“什么是异常?”。
在该部分中,我引用:
...异常不应该被用作程序正常流程的一部分;应为意外事件保留例外。
虽然在您的情况下是否使用异常存在争议,但我会说不 - 因为您可能需要捕获一个请求中所有可能的输入错误,并反映在表单上,以便用户更正这些值。
现在我想起来了,是的,你应该在这里使用异常。这就是防御性编码的方式。如果您已经期望将有效参数传递到类中Customer,那么代码应该抛出异常以防止该类的无效使用(例如,由另一个程序员使用)。在这种情况下,您应该有另一个输入验证器来在到达类之前验证用户对应用程序的输入Customer。