问题
Perhaps in the app I have a feature allowing users to send feedback using a form with some validation logic:
- name can be empty
- feedback message should be at least 5 characters
Where would you put these validation logic, either in domain layer
as business logic or in presentation layer
as UI logic?
These logic are applied for all applications (android, iOS, web). Please note that we already had server side validation.
回答1:
I think many developers do that in Presentation
layer, specifically in ViewModel/Presenter/Controller
(not in Activity/Fragment/View!
). My approach is to put that logic in Domain
layer. Why?
- Is it presentation logic or domain logic? Presentation logic is something you decide "mapping render model", "format of render model", "how to render", "what color, what size, which text", "how long will it stay on screen" etc... If validation is presentation logic, why does backend code have same validation control? From my perspective, validation is Domain logic.
- Why validation is Domain logic? Who decides if username can be 20 char at max? Business rule decides. Who decides number of max items in shopping basket? Business rule decides. The length of username is decision of business, and that rule applies in everywhere in the project. CreateProfile/ UpdateProfile/ Register etc.. all have same max-20char-username rule. That length control (validation) code should reside in Domain layer.
- What is the flow if validation code is in Domain layer? User clicks button in View. ViewModel/Presenter calls domain layer function. Domain layer function validates input data. If there are invalid input parameters, it returns
ValidationException
with explanation.ValidationException
will contain list of invalid parameters, type of validation they failed (minLength, maxLength, emailPatternMismatch etc..), what is expected (20 char at max etc..).ViewModel/Presenter/Controller
gets thisValidationException
and here we have Presentation logic. Now it decides what to render, how to render. Do we render error of all invalid inputs or only first invalid input? What text/color should be shown (based on data in ValidationException) ? Do we render error as popup/textView/tooltip? After all presentation decisions are made and new model is created,View
just! renders using that model. - Another point is, in Domain layer, where should be validation code? In UseCase functions or in Models (why not) itself? IMHO, there should be Stateless Generic Interface/Class that has generic validation logics. And after that point, each UseCase class can implement ValidationInterface or inject it as Class object. If multiple UseCases need same validation, validation control logic will be duplicated. What happens if we put validation logic in Model itself? Model would implement ValidationInterface (which has stateless pure functions only!) and have
fun validate():ValidationOutcome
function. I don't think it is problem to put validation logic of Business Model in itself. All UseCases would callmodel.validate()
only. There is dependency between Model and ValidationOutcome.
回答2:
I'm not an android nor ios developer but I have some experience in web dev. This question is asked constantly by some coworkers. For me, the answer is both.
For example, if you have the validation logic in the presentation layer, whenever a user sends a bad input, you must go to the server, validate and then return the errors. To avoid asking the server you could validate the presentation layer with html5 or javascript. If some input is bad, this is shown to the user and there is no communication with the server (so you avoid one request). But this validation can be skipped easily, so if a user changes something or do the request with a tool (like postman) this validation doesn't happen. So, you can not be sure the data you are receiving is ok. For that, you need the server validation too.
For me, this is the safer solution and you only use UI to avoid bad request to the server.
Hope this helps.
来源:https://stackoverflow.com/questions/57603422/clean-architecture-where-to-put-input-validation-logic