В системе, над которой я сейчас работаю, я следую 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 должны знать, как вызвать IsValidForPersistence () до SaveCustomer (), в противном случае недопустимые данные сохраняются. Я мог бы создать ограничения БД, чтобы защититься от этого на уровнях SQL, но это похоже на пометку.
Похоже, что IsValidForPersistence () следует переместить в CustomerDao.SaveCustomer (), но затем мне нужно реорганизовать сигнатуру SaveCustomer (), чтобы включить ссылки на класс ValidationErrors. Прежде чем углубиться в этот масштаб рефакторинга, я хотел бы получить отзывы от других о распространенных / предпочтительных шаблонах для решения этих проблем.
Спасибо