Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Validating model classes in setter methods

I would like to ask your ideas about designing best validation approach for below requirements:

We have a User model class and depending on it is status we can update some specific fields. As you can see, changeability of the model class depends on its status field.

  • If the status of user is ACTIVE then all fields (name, surname, password ....) can be updated.
  • If the status of user is INACTIVE only password can be updated.
  • If the status of user is BLOCKED then name and surname can be updated.
  • If the status of user is DELETED then update operation is not allowed for any field.

Obviously, it can be done simply by adding a UserValidator class and before setting values in setter methods I can call my UserValidator to check if the operation is allowed or not. However, it has a drawback (?): what will happen if there will be new field (let's say maritalStatus) and dev who adds that field forgets to call UserValidator before setting maritalStatus?

Other ways of solving this problem that I can think of:

  1. Using custom annotations by extending CustomValidator. However, it won't work as annotation cannot know the previous values of object. I mean, the isValid() method of CustomValidator won't know if the name field has changed or not (it was "John" and now dev wants to change it to "Jack")
  2. Proxy pattern could be useful but not sure if it is good idea to use proxy for model objects.

I've seen that the decorator pattern can be used for this problem but I don't understand how. I think validating model class is beyond the responsibility of a decorator design.

public class User {
    private Integer id;
    private String name;
    private String surname;
    private String password;
    private Status status;
    // setters
}

public enum Status {
    ACTIVE, DELETED, INACTIVE, BLOCKED
}
like image 295
sinan Avatar asked Jun 06 '26 02:06

sinan


1 Answers

I suggest you to use intention-revealing interfaces instead of setter/getter

E.g.

public class User {
   private Integer id;
   private String name;
   private String surname;
   private String password;
   private Status status;


   void rename(String newName, String newSurname){
      if(Status.INACTIVE.equals(status) || Status.DELETED.equals(status))
          throws new Exception("You cannot rename a inactive or deleted user");

      this.name = newName;
      this.surname = newSurname;
   }
    .....

}  
like image 158
Claudia Chersin Avatar answered Jun 08 '26 15:06

Claudia Chersin