论坛首页 Java企业应用论坛

关于ddd中validation.

浏览 2514 次
精华帖 (0) :: 良好帖 (11) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-06-23   最后修改:2009-06-23
   对于validation和Authentication Authorization还没有很好的想法.

   在ddd中validation分为几种.
   一种input validation,这时候对参数进行验证等.如例.
   一种self entity validation,网上有这方面讨论,是不是应该aways validate,将validate放入构造函数.


   关于是通过control flow还是throw exception来处理validation,还特意做了个测试,一开始用log.debug发现结果误差很大,后来发现去掉Log,快了好多,Log还是挺占资源的.去掉log发现,在速度方面,后者是前者二倍左右.都很小,具体测试没有保存.



下面是例子.
为了更好理解,我说下流程.
    首先在command里先检测request中的参数,同时通过trim/uppercase处理参数之后,装入command.如果抛出异常直接跳转.

    然后新建user,在创建的时候进行validation,包括如下username,password,email是否为合法字符组成,判断username和email是否已经存在.如果存在抛出异常,将异常返馈信息装入messagemodel.最后跳转.

  1. entity
  
@javax.persistence.Entity
@Table(name = "D_USER")
public class User implements Entity<User>, Validatable {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "USER_ID")
    private long id;
    @Column(unique = true)
    private String name;
    private String password;
    @Column(unique = true)
    private String email;

    /**
     * Hibernate need.
     */
    protected User() {
    }

    /**
     * @param email
     * @param name
     * @param password
     */
    public User(String name, String email, String password) {
        validate();
        this.email = email;
        this.name = name;
        this.password = password;
    }

    public String username() {
        return this.name;
    }

    public String password() {
        return password;
    }

    public String email() {
        return email;
    }


    @Override
    public boolean sameIdentityAs(User other) {
        return id == other.id;
    }


    @Override
    public void validate() {
       // new UserValidator().isValid();
    }


}


  疑问:在网上看到一些说eliminate setter.value object还可以理解,因为是immutable.entity如何要更新该如何是好.或许我理解错了.实在不想将抛出异常定义为checked exception.可以灵活一些,但是..

  2.repository
public interface UserRepository {
    public void store(User user);
    public User find(User user);
}


3.command:处理request参数,这阶段可能有validation,convert(例如uppercase等),filter

public class AccountCommand {
    private String username;
    private String password;
    private String passwordCopy;
    private String email;
    public AccountCommand(HttpServletRequest request) throws IllegalParamException {
        Map<String, String[]> params = request.getParameterMap();
        username=getParamValues(params,"username")[0];
        String[] passwords=getParamValues(params,"password");
        password=passwords[0];
        passwordCopy=passwords[1];
        email=getParamValues(params,"email")[0];
        filter();
        validate();
    }

    public String username(){
        return username;
    }

    public String password(){
        return password;
    }

    public String email(){
        return email;
    }

    private String[] getParamValues(Map<String, String[]> params,String feild) throws IllegalParamException {
        String[] result=null;
            if(params!=null){
               result=params.get(feild);
            }
        if(result==null) throw new IllegalParamException();
        return result;
    }

    public void filter(){
        this.username=username.trim();
        this.password=password.trim();
        this.passwordCopy=passwordCopy.trim();
        this.email=email.trim();
    }

    public void validate( ) {
       MessageModel messageModel=new MessageModel();
       final  String PASSWORD_FEILD="PASSWORD";
        try {
            ValidateRules.notBlank(password);
            ValidateRules.notBlank(passwordCopy);
        } catch (NullValidationException e) {
                messageModel.newMessage(PASSWORD_FEILD,UserMessage.NULL);
        } catch (BlankValidationException e) {
           messageModel.newMessage(PASSWORD_FEILD,UserMessage.BLANK);
        }

        if(!password.equals(passwordCopy)){
            messageModel.newMessage(PASSWORD_FEILD,UserMessage.PASSWORD_DIFFERENT);
        }

        throw new ValidationException(messageModel);
    }
}


   4.servlet
  
public class AccountServlet extends HttpServlet {
    private UserRepository userRepository;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        MessageModel messageModel = new MessageModel();
        AccountCommand command = null;

        try {
            command = new AccountCommand(req);
        } catch (ValidationException e) {
            messageModel.addMessages(e.getMessages());
        } catch (IllegalParamException e) {
            goTo(req, resp, "", true);
        }

        try {
            User user = new User(command.username(), command.email(), command.password());
            userRepository.store(user);
        } catch (ValidationException e) {
            messageModel.addMessages(e.getMessages());
        }
        goTo(req, resp, "", true);
    }

    private void goTo(HttpServletRequest req, HttpServletResponse res, String view, boolean method) throws IOException, ServletException {
        if (method) {
            req.getRequestDispatcher(view).forward(req, res);
        } else {
            res.sendRedirect(view);

        }
        return;
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //super.doPost(req, resp);
    }
}


   5.validatable && validator &&userValidator

 
public class UserValidator implements Validator<User> {
    private UserRepository userRepository;

    private void existAccount(User entity) throws  EmailExistValidationException, UserNameExistValidationException {
        User user=userRepository.find(entity);
       if(user!=null){
           if(entity.username()==user.username()){
               throw new UserNameExistValidationException();
           }else if(entity.email()==user.email()){
               throw new EmailExistValidationException();
           }
       }
    }

    @Override
    public boolean isValid(User entity) {
        return !brokenRules(entity).hasMessages();
    }

    @Override
    public MessageModel brokenRules(User entity) {
        MessageModel messages = new MessageModel();
        final String USERNAME_FEILD = "USERNAME";
        final String EMAIL_FEILD = "EMAIL";
        final String PASSWORD_FEILD = "PASSWORD";

        try {
            ValidateRules.username(entity.username());
        } catch (UserNameValidationException e) {
            messages.newMessage(USERNAME_FEILD, UserMessage.USERNAME_ERROR);
        } catch (NullValidationException e) {
            messages.newMessage(USERNAME_FEILD, UserMessage.NULL);
        } catch (BlankValidationException e) {
            messages.newMessage(USERNAME_FEILD, UserMessage.BLANK);
        }



        try {
            ValidateRules.password(entity.password());
        } catch (PasswordValidationException e) {
            messages.newMessage(PASSWORD_FEILD, UserMessage.PASSWORD_ERROR);
        } catch (NullValidationException e) {
            messages.newMessage(PASSWORD_FEILD, UserMessage.NULL);
        } catch (BlankValidationException e) {
            messages.newMessage(PASSWORD_FEILD, UserMessage.BLANK);
        }


        try {
            ValidateRules.email(entity.email());
        } catch (EmailValidationException e) {
            messages.newMessage(EMAIL_FEILD, UserMessage.EMAIL_ERROR);
        } catch (NullValidationException e) {
            messages.newMessage(EMAIL_FEILD, UserMessage.NULL);
        } catch (BlankValidationException e) {
            messages.newMessage(EMAIL_FEILD, UserMessage.BLANK);
        }


        try {
            existAccount(entity);
        } catch (EmailExistValidationException e) {
            messages.newMessage(EMAIL_FEILD,UserMessage.EMAIL_EXIST);
        } catch (UserNameExistValidationException e) {
            messages.newMessage(USERNAME_FEILD,UserMessage.USERNAME_EXIST);
        }

        return messages;


    }
}


 
public interface Validator<T> {
    public boolean isValid(T entity);
    public MessageModel  brokenRules(T entity);


}


6.Message && UserMessage

public enum UserMessage  implements Message<UserMessage>  {
    NULL,
    ALL_RIGHT,
    BLANK,
    USERNAME_ERROR,  //there are some error in username,eg.illegal characters
    USERNAME_EXIST,  //there are no such account's username
    PASSWORD_ERROR,  //illegal password
    PASSWORD_DIFFERENT,//repeate password error
    PASSWORD_ERROR_DIFF,
    EMAIL_ERROR,       //wrong email format
    EMAIL_EXIST,
    UNKNOW_ACCOUNT,   //there are no such account.    
    UNKNOW_FEILD;


    @Override
    public UserMessage get() {
        return this;
    }

   
}


   8.MessageModel

 
public class MessageModel {
     Map<String, Set<Message>> messages=new HashMap<String,Set<Message>>();

    public void newMessageSet(String key,Set<Message> messageSet){
        messages.put(key,messageSet);
    }
    public void newMessage(String key,Message message){
        Set<Message> messageSet=  messages.get(key);
        if(messageSet==null){
            messageSet=new LinkedHashSet<Message>();
        }
        messageSet.add(message);
        messages.put(key,messageSet);
    }

    public void addMessages(Map<String, Set<Message>> newMessages){
         if(newMessages!=null){
             for(Map.Entry<String,Set<Message>> item:newMessages.entrySet()){
                 String key=item.getKey();
                 Set<Message> messageSet=item.getValue();
                 if(messages.containsKey(key)){
                     for(Message ms:messageSet){
                         newMessage(key,ms);
                     }
                 }else{
                     newMessageSet(key,messageSet);
                 }
             }
         }
    }

    public void addMessages(MessageModel messageModel){
        addMessages(messageModel.getMessages());
    }

    public Map<String, Set<Message>> getMessages(){
        return this.messages;
    }

    public boolean hasMessages(){
        return this.messages.size()>=1;
    }
}

 
all comment are welcome.谢谢大伙了..
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics