There are different approaches when it comes to validating properties of an object in Kotlin, which indirectly involve validating UI fields if you are using this great language for Android development.
Let’s see how we can implement validation keeping in mind reusability and code readability.
For that we are going to implement two classes that are going to validate that a string contains a certain letter and that an integer is between a specified range.
Defining our validator structure
We are going to need four main actors to implement this feature:
- ValidateWith: this is the Annotation Class which is going to be assigned to each property we would like to validate.
- Validator: an interface for each of our validators to implement, so that we can later check if the property of the class is annotated with the
- ValidationError: another interface to model our errors. In my case I’m going to return an error message, but you can change it to return an
Exceptionobject for example to throw or manage later.
- ValidatorUtils: contains the code that is going to be called to pass the object to validate. It also connects the
ValidateWithannotation class with each
Creating the Annotation Class
This feature is heavily going to depend on a programming concept called Reflection. I recommend that you check this StackOverflow answer if you’ve never heard of it.
As you can see in the following code snippet, we are defining an
Annotation Class which takes a
Our validator property is going to contain a reference to the validator we want to use, represented in a class, thanks to KClass.
As we are going to validate properties of a class we need to add the
Target tag as a
Field. You can see all available options in the official Kotlin documentation here.
Jumping into the validator code
Validator interface is going to be implemented by each of the Validators as we will see below.
It’s only method is going to take the field that we are validating, and it’s value. Then it’s going to return a
ValidationError, or null if validation is successful.
ValidationError is another interface that is going to allow us to return concrete error for each of our validations.
Here you have one simple implementation that we are going to use for our validators.
Now that we have our interfaces and an error defined, we can now implement our validators.
You can check in the code below how we are making sure the conditions which we specified at the beginning of the article are matched, and if not, a
FormatError is returned with a message.
With this approach you can inject each Validator at whatever point you are in your project, reusing the same code, avoiding the need of injection libraries.
To finish let’s see the code that we are going to call to validate an object. It has one public function and two auxiliary private ones.
validate method is going to:
- Verify that the value passed is not null.
- Read the properties of the class that contains the fields that we want to validate thanks to Reflection.
- For each field, we are going to check that the
ValidateWithtag is applied and that the class reference passed to it implements the
- Finally, we are going to execute each
Validator. Using Reflection in the
validateFieldsmethod we can call the constructor of each
Validatorimplementation and run our code to validate the value.
In my case I’m developing this project with Gradle. With this in mind if you want to use the same code, don’t forget to add the following dependency to your
build.gradle.kts file to use the
Running the validator
Here is a snippet to test the code above, where we just need to call the
ValidatorUtils object and pass it the instantiated class we would like to validate.
If both properties of the Android class have values that are valid, the
validate method is going to return an empty list, but if one or every of them fails to match the constraints established in the validators, we are going to see the following outputs.
To finish, here you have access to the repo with the code if you want to save it.
If you want to read more content like this and support me, don’t forget to check the rest of the bolg or subscribe here to get an email every time I publish new content.