在我目前正在使用的系統中,我通過分離域業務規則與持久性約束的驗證來跟蹤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級別創建DB約束來防止這種情況發生,但是這種感覺就像是一團糟。
好像IsValidForPersistence()應該被移入CustomerDao.SaveCustomer(),但是我必須重構SaveCustomer()的簽名以包含對ValidationErrors類的引用。在深入探討重構之前,我想從其他人那裏獲得一些關於處理這些問題的常見/優先模式的反饋。
感謝