在我目前正在开发的系统中,我通过分离域业务规则与持久性约束的验证来关注SRP(我认为!)。让我们使用过度使用的客户示例。假设客户必须拥有有效的邮政编码,街道地址和名称,以满足系统的业务规则。让我们进一步说,客户选择的用户名在所有客户中必须是唯一的,我将其定义为持久性约束。请考虑以下“未准备好生产”伪代码:
public interface IPersistenceValidator<T>
{
bool IsValidForPersistence(T domainObj, IList<ValidationError> validationErrors);
}
public interface IValidatable
{
bool IsValid(IList<ValidationError> validationErrors);
}
public class Customer : IValidatable
{
public bool IsValid(IList<ValidationError> validationErrors)
{
//check for business rule compliance
}
}
public class CustomerDao : IPersistenceValidator<Customer>
{
public bool IsValidForPersistence(Customer domainObj, IList<ValidationError> validationErrors)
{
//check for persistence constraint compliance (user name is unique)
}
public bool SaveCustomer(Customer customer)
{
//save customer
}
}
上面定义的类可能会按如下方式连接到服务类:
public class SaveCustomerService
{
private CustomerDao _customerDao;
public SaveCustomerService(CustomerDao customerDao)
{
_customerDao = customerDao;
}
public bool SaveCustomer(Customer customer)
{
IList<ValidationError> validationErrors = new List<ValidationError>();
if (customer.IsValid(validationErrors))
{
if (_customerDao.IsValidForPersistence(customer, validationErrors))
{
return _customerDao.SaveCustomer(customer);
}
else
{
return false;
}
}
else
{
return false;
}
}
}
我对这种方法的主要关注是,CustomerDao的未来消费者必须知道在SaveCustomer()之前调用IsValidForPersistence(),否则会无效的数据被持久化。我可以在SQL级别创建数据库约束以防止这种情况,但这感觉就像一个kludge。
似乎应该将IsValidForPersistence()移动到CustomerDao.SaveCustomer()中,但是我必须重构SaveCustomer()的签名以包含对ValidationErrors类的引用。在我深入研究重构之前,我想从其他人那里获得一些关于处理这些问题的常见/优先模式的反馈。
谢谢
答案 0 :(得分:0)
如果您想解决验证问题,请先检查 HERE ;
public class Address {
@NotNull private String line1;
private String line2;
private String zip;
private String state;
@Length(max = 20)
@NotNull
private String country;
@Range(min = -2, max = 50, message = "Floor out of range")
public int floor;
...
}
无论如何你必须检查数据库中的用户名。您可以自定义验证(例如go和check DB,这是唯一的)。查看另一个指向细节的链接。