TL; DR
Where/When to check data format in MVVM + Repository Pattern is the best practice? Any suggestion or theory?
The Scene
Our team is working on an Android Project. We have a MVVM+repo structure:
View > View Model > Repository > Model
In some feature, we need to pass data from View all way through the struct, such as "Uploading an Item":
Input
[data] --------------------------->
View > View Model > Repository > Model
Due to design, data need to match specific format, Such as "check if it is an email", "check if it exceeds 200 characters", etc. If it doesn't, show errors at View:
Output
[error] <- [- - - somewhere - - -]
View > View Model > Repository > Model
The question comes along with this process: If there's a need to check if data is format-correct, when or where to check is the best practice?
The Options and Thoughts
According to the structure, there's a few options to do format-check/block:
- View / View Model
- Repository / Model
- Others
- All
For us, we feel all of the options seems legit, yet some risks also.
View or View Model
In my understanding, View Model combines the data input by user, and send them to repository. In some situation even View can achieve the format checks, ex. Android EditText
can auto-check length or legit characters.
However, making format-check in V/VM implies that some business logic might come into V/VM layer. For example, checking that "if data has already been added into database" is not appropriate to do in V/VM.
Repository or Model
This is the most attractive answer so far -- if we put checking function here, we can also include the business logic here, making it easier to manage logic part (and feeling less guilty lol).
However, if the View requires instant-check, then putting all the checking functions here might cause the Repo unnecessary-fat.
For example, imagine a form View with 4 fields, each of it has its own format-limit, such as length, characters, regex, or even cross-field relations (if A is checked then B is not allowed to write, etc.).
If we put data-checking functions all inside Repo, this means that Repo has to provide at least 4 data-checking functions, and still having difficulty to deal with cross-field relations, AND still need to provide the sendOutForm
functions.
Util or Helper class
Another option comes in mind is the helper/util class. It might be appropriate, however it has the same questions as View option: some business logic is not viable in util class, and helper class (with too many reference/logic) might also cause function management problem.
Check More/All: Pros and Cons
Ideally, making format-checks as many as we can is the most secure option. However, it will reduce function flexibility.
For example: the data originally requires description
field to be necessary, but later decided to make it optional after the product published a while. If we make null/empty checks of description
field at all places, it will cause a lot of time to make the updates, taking more time to check where hasn't been modified.
That's all of our thoughts now. How would you archive the data-check? And why? I'd like to know.