2009-12-15 97 views
1

在我目前正在使用的系統中,我通過分離域業務規則與持久性約束的驗證來跟蹤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類的引用。在深入探討重構之前,我想從其他人那裏獲得一些關於處理這些問題的常見/優先模式的反饋。

感謝

回答

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; 
    
         ... 
    

    }

    反正你必須檢查數據庫的用戶名。您可以自定義您的驗證(如去和檢查DB是唯一的)。看看另一個細節的鏈接。

  • 檢查冬眠validator
  • 檢查Using the Validator framework從JBoss的
  • 您可以閱讀驗證領域層partIpartII,這不是Java,但邏輯是很重要的。