2009-12-15 21 views
1

Dans le système sur lequel je travaille actuellement, je suis SRP (je pense!) En séparant la validation des règles de gestion de domaine et des contraintes de persistance. Utilisons l'exemple client surutilisé. Supposons qu'un client doit avoir un code postal, une adresse et un nom valides pour satisfaire aux règles de gestion du système. Disons en outre que le nom d'utilisateur sélectionné du client doit être unique pour tous les clients, que je définis comme une contrainte de persistance. S'il vous plaît considérer ce qui suit « pas prêt pour la production » pseudo-code:Validation d'un objet de domaine pour la persistance

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 
    } 
} 

Les classes définies ci-dessus pourrait se câblé dans une classe de service comme suit:

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

Ma principale préoccupation avec cette approche est que les futurs consommateurs de CustomerDao doivent savoir appeler IsValidForPersistence() avant SaveCustomer(), sinon les données non valides sont conservées. Je pourrais créer des contraintes DB pour éviter cela au niveau SQL, mais cela ressemble à un kludge.

Il semble que IsValidForPersistence() doive être déplacé dans CustomerDao.SaveCustomer() mais ensuite je dois refactoriser la signature de SaveCustomer() pour inclure des références à la classe ValidationErrors. Avant de plonger dans ce grand refactoring, je voulais obtenir des commentaires de la part des autres sur les modèles communs/préferés pour traiter ces problèmes.

Merci

Répondre

0
  • premier chèque HERE si vous voulez résoudre votre problème de validation comme;

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

    }

    de toute façon vous devez vérifier le nom d'utilisateur dans la base de données. Vous pouvez personnaliser votre validation (comme aller et vérifier la DB pour cela est unique). Regardez un autre lien vers le détail.

  • Vérifiez mise en veille prolongée validator
  • Vérifier Using the Validator framework de jboss
  • Vous pouvez lire la validation dans la couche de domaine partI, partII, ce n'est pas java mais la logique est importante.