【发布时间】:2017-01-06 13:23:21
【问题描述】:
正如 DDD 从业者所建议的那样,业务规则的验证必须在域对象(实体、值对象和域服务)内实现,并遵循它们自己的上下文,我读过我们应该在某个地方进行技术验证(例如检查长度、正确输入格式,正确的数据类型,...)在域模型之外和应用层之类的地方,以保持域对象清晰。
现在 我的问题是:
如果我们有信用卡号的值对象,我们是否仍应将技术验证排除在值对象之外? 换句话说,当我们处理值对象时,“自我验证”一词不涉及技术验证?
如果不正确的借记卡号码甚至电子邮件地址有可能破坏业务规则,那该怎么办?
为了更清楚,请注意这个代表借记卡号码的值对象:
public class DebitCardNumber : ValueObject
{
public string Number { get;private set; }
public CreditCardNumber(string number)
{
Validation(number);
this.Number = number;
}
private void Validation(string number)
{
if (String.IsNullOrWhiteSpace(number))
{
throw new CardNumberCanNotBeEmptyException();
}
if (number.Length != 16)
{
throw new CardNumberLengthMustBeSixteenDigitException();
}
int sum = 0;
for (int i = 1; i <= 16; i++)
{
if (!char.IsDigit(number[i - 1]))
{
throw new ValueContainsSomeNonDigitCharacterException();
}
int m = (i % 2 == 0 ? 1 : 2);
int a = (int.Parse(number[i - 1].ToString()) * m);
while (a > 9)
{
a -= 9;
}
sum += a;
}
if ((sum % 10) > 0)
{
throw new ValueIsNotCorrectAsACardNumberException()
{ Message = "Perhaps some digits has been entered in wrong order or they are incorrect." };
}
}
}
根据此代码,有一个验证方法可以执行算法来确定卡号的格式是否正确? 你认为它适合这种类型的验证吗?
【问题讨论】:
-
如果值对象无效,应该无法构造。您应该将所有这些验证规则放在构造函数中,以防止创建无效对象。