avatarKamlesh Lakhani

Summary

The provided web content outlines a set of Kotlin functions and use cases for validating user input such as email, password, and phone number within an Android application, adhering to Clean Architecture principles.

Abstract

The web content details a structured approach to input validation in an Android application, utilizing Kotlin programming language. It includes a core section that defines functions to validate if a string is a number, if an email is valid, and if a password meets specific criteria. The domain section introduces a ValidationResult data class for encapsulating validation outcomes and a BaseUseCase interface for executing use cases. Specific implementations for validating email, password, and phone number are provided through ValidateEmailUseCase, ValidatePasswordUseCase, and ValidatePhoneNumberUseCase classes, respectively. These use cases check for blank input, valid email format, password complexity, and phone number content, returning a ValidationResult object with either a success confirmation or an error message resource. Lastly, a MainViewModel is referenced, which encapsulates the use of these validation use cases in a higher-level component.

Opinions

  • The code snippets emphasize the importance of input validation in Android applications.
  • The use of Clean Architecture is implied through the separation of validation logic from the user interface, promoting maintainability and testability.
  • The ValidationResult class is designed to communicate validation outcomes effectively, possibly to the UI layer, by including both a success status and an optional error message.
  • Regular expressions and built-in Android utilities (e.g., Patterns.EMAIL_ADDRESS) are leveraged for efficient and reliable input validation.
  • The BaseUseCase interface suggests a template method pattern, providing a standardized way to execute business logic across different use cases.
  • The code examples are likely intended for educational purposes, showcasing how to implement robust validation within an Android application's domain layer.

Tips | Clean Architecture | Validation | Android

core

import android.util.Patterns

// this fun use for check if value is number
fun isNumber(value: String): Boolean {
    return value.isEmpty() || Regex("^\\d+\$").matches(value)
}

fun isEmailValid(email: String): Boolean {
    return Patterns.EMAIL_ADDRESS.matcher(email).matches()
}

fun isPasswordValid(password: String): Boolean {
    return password.any { it.isDigit() } &&
            password.any { it.isLetter() }
}
//usecase/BaseUseCase.kt
interface BaseUseCase<In, Out> {
    fun execute(input: In): Out
}

domain

//model/ValidationResult.kt
data class ValidationResult(
    val successful: Boolean,
    val errorMessage: UiText? = null
)
//usecase/ValidateEmailUseCase.kt
class ValidateEmailUseCase: BaseUseCase<String, ValidationResult> {
    override fun execute(input: String): ValidationResult {
        if (input.isBlank()) {
            return ValidationResult(
                successful = false,
                errorMessage = UiText.StringResource(resId = R.string.strTheEmailCanNotBeBlank)
            )
        }
        if (!isEmailValid(input)) {
            return ValidationResult(
                successful = false,
                errorMessage = UiText.StringResource(resId = R.string.strThatsNotAValidEmail)
            )
        }
        return ValidationResult(
            successful = true,
            errorMessage = null
        )
    }
}
//usecase/ValidatePasswordUseCase.kt
class ValidatePasswordUseCase : BaseUseCase<String, ValidationResult> {
    override fun execute(input: String): ValidationResult {
        if (input.length < 8) {
            return ValidationResult(
                successful = false,
                errorMessage = UiText.StringResource(resId = R.string.strThePasswordNeedsToConsistOfAtLeastEightCharacters),
            )
        }

        if (!isPasswordValid(input)) {
            return ValidationResult(
                successful = false,
                errorMessage = UiText.StringResource(resId = R.string.strThePasswordNeedsToContainAtLeastOneLetterAndDigit),
            )
        }
        return ValidationResult(
            successful = true
        )
    }
}
//usecase/ValidatePhoneNumberUseCase.kt
class ValidatePhoneNumberUseCase : BaseUseCase<String, ValidationResult> {

    override fun execute(input: String): ValidationResult {
        if (input.isBlank()) {
            return ValidationResult(
                successful = false,
                errorMessage = UiText.StringResource(resId = R.string.strThePhoneCanNotBeBlank),
            )
        }

        if (!isNumber(input)) {
            return ValidationResult(
                successful = false,
                errorMessage = UiText.StringResource(resId = R.string.strThePhoneNumberShouldBeContentJustDigit),
            )
        }

        return ValidationResult(
            successful = true,
            errorMessage = null
        )
    }
}
//viewmodel

class MainViewModel : ViewModel() {

    private val validateEmailUseCase = ValidateEmailUseCase()
    private val validatePasswordUseCase = ValidatePasswordUseCase()

}
Clean Architecture
Tips
Validation
Android
Jetpack Compose
Recommended from ReadMedium