Vintage appMaker의 Tech Blog

[kotlin] 조건문을 최소화한 String validation 본문

강좌, 연재/kotlin 강좌

[kotlin] 조건문을 최소화한 String validation

VintageappMaker 2022. 8. 21. 14:52

 

앱개발을 하면서 화면의 문자열을 길이, 한영, 숫자 등등을 채크해야 하는 경우가 많이 발생한다. 그럴 경우, 똑같은 로직의 코드를 변수명만 달리하여 copy  & paste 수준으로 활용할 때가 많다. 이렇게 하다보면 나중에 귀찮은 일이 발생한다. if 문이 너무 남발된다. 그러다보니 android에서는 validation 관련 annotation을 제공하는 모듈들이 많이 제공된다. kotlin poet을 이용하여 비슷한 유형의 source를 만들어주기도 한다. 그러나 그것도 가끔은 귀찮아 질 때가 있다. 

 

- 비교문을 모듈화 하고 
- 부분적인 오류있으면 callback으로 호출

- 전체 validation 후, 결과값 리턴

 

을 하기위해 아래와 같은 간단한 소스를 구현했다. 
앱에서 사용자 가입정보같이 다양한 문자열 정보를 validation할 때 유요하게 사용할 수 있다. 

import java.util.regex.Pattern

sealed class checkFunc
class ValidateFunc {
    var fnValidate : MutableList<checkFunc> = mutableListOf()

    fun add(item : checkFunc) = fnValidate.add(item)

    fun validate () : Boolean{
        var bRst = true
        fnValidate.forEach {
            when (it){
                is chkSizeLimted -> {
                    if(it.isTrue == false ) it.onFail(it.value.length)
                    bRst = bRst && it.isTrue
                }
                is  chkPattern -> {
                    if(it.isTrue == false ) it.onFail()
                    bRst = bRst && it.isTrue
                }
            }
        }

        fnValidate.clear()
        return bRst
    }
}

data class chkSizeLimted (
    var value   : String = "",
    var onFail  : (Int) -> Unit ={},
    var max : Int = 0,
    var min  : Int = 0) : checkFunc(){
        var isTrue : Boolean = false
        get (){ if (value.length > min && value.length <max) return true else return false }
}

data class chkPattern (
    var value   : String = "",
    var onFail  : () -> Unit = {},
    var sPattern : String = "") : checkFunc(){
    var isTrue : Boolean = false
        get (){ if ( Pattern.matches(sPattern, value ) ) return true else return false }
}

// DSL
fun ValidateDSL(block : ValidateFunc.() ->Unit) = ValidateFunc().apply(block)
fun ValidateFunc.Limited(block : chkSizeLimted.() ->Unit) {
    add(chkSizeLimted().apply(block))
}

fun ValidateFunc.Regex(block : chkPattern.() ->Unit) {
    add(chkPattern().apply(block))
}

fun ValidateFunc.checkAll(block : ValidateFunc.(Boolean) ->Unit) {
    block(validate())
}

fun main() {
    val checkValid = ValidateFunc()

    val sTest1  = "123456"
    val sTest2  = "움하하하"

    checkValid.add(
        chkSizeLimted(value= sTest1, min=5, max = 12,
            onFail = { n -> println("$sTest1 <- $n is not allowed") })
    )

    checkValid.add(
        chkPattern(value= sTest1, sPattern = "^[0-9]*\$",
            onFail = { println("$sTest1 <- 숫자가 아닙니다") })
    )

    println ("${sTest1} 결과는 ${checkValid.validate()}")

    // DSL 처리
    ValidateDSL {
        Limited {
            value = sTest1
            max   = 10
            min   = 8
            onFail = { n -> println("$sTest1 <- $n is not allowed")}
        }

        Regex {
            value    = sTest1
            sPattern = "^[가-힣]*\$"
            onFail   = {println("$sTest1 <- 한글아님")}
        }

        Regex {
            value    = sTest2
            sPattern = "^[0-9]*\$"
            onFail   = {println("$sTest2 <- 숫자가 아님")}
        }

        checkAll{
            b -> println ("ValidateDSL{} 테스트 결과는 $b")
        }
    }
}

'강좌, 연재 > kotlin 강좌' 카테고리의 다른 글

왕초보를 위한 Kotlin  (0) 2020.07.23
[Android] 왕초보를 위한 코틀린 -kotlin  (0) 2020.07.16
Comments