OO design patterns to use for validation

2019-03-09 04:14发布

I am in the process of writing some validation code based on these assumptions:

  • Validation code must be in an external class
    • i.e. no data class contains it's own validation
  • The same object can be validated in different ways
    • e.g. validate syntax only; validate against DB look-ups; validate against duplicates; etc
  • Validation output can be different depending on what needs it
    • e.g. output a single error message; output a list of all validation errors; similar but in JSON format and including error codes; etc

What combination of OO design patterns are best to solve this? A factory might be a good way to get a specific validator, but are their better approaches?

4条回答
疯言疯语
2楼-- · 2019-03-09 04:21

If you're doing any sort of of GUI work, you should take a look at JGoodies Validation: http://www.jgoodies.com/downloads/libraries.html (also some articles here: www.jgoodies.com/articles/).

I would create a validator for any class that needs validation. You can actually create more than one validator if you need different ways of validating, e.g. strict or not. You can group common functionality and methods into classes like AbstractValidator and ValidationResult (which may have a list of errors, severity, etc.).

Be wary of over-design. Try starting with something simple like:

new UserValidator().validate(user)

or to validate a view:

new UserPanelValidator().validate(userPanel)

It does depend on your architecture though. For example, if you automatically propagate input from the view to the domain, then you don't need to do as much validation at the view level.

查看更多
Ridiculous、
3楼-- · 2019-03-09 04:28

One size does not fit all! Make it simple!

Provide validators with common methods/interface to output data, categorize warnings, filter/process warnings raised more than once. Do not create any sophisticated way of validation itself, at least not before writing a few real life validators.

Move out of the way and let the validators do what they are supposed to do:

for validator in all_validators:
    validator.validate(model)

查看更多
Ridiculous、
4楼-- · 2019-03-09 04:28

I had this same problem and I found the visitor pattern to be really effective at decoupling the validation logic from the data object. You'll need to instrument your data class hierarchy with accept( visitor ) methods, but if you're building everything that's simple enough. Even if you're using a third-party hierarchy without visitor support, you can create wrappers that provide the accept traversal tree and that's pretty close to having the method inside the class.

To perform the different validation you implement a different validator class and pass it to the accept method on the root object. I was also able to create other utility visitors around the model which allowed me to create a generator visitor that filled in all the fields with sample/random data. I went a little visitor crazy on it because I was so excited. You can probably tell I'm still excited about it, especially having the change to tell someone else about it.

查看更多
狗以群分
5楼-- · 2019-03-09 04:37

I think I am doing the same thing right now.
The pattern that applies here is the Filter pattern and the Filter Chain.

Each filter validates against one "way" (as you call them).
First for syntax, second for Db lookups etc (from your second bullet).

查看更多
登录 后发表回答