1
resposta

[Sugestão] Criação de Utils e Extension functions

Assim que começei a realizar o curso, existe muita repetição de código como a possibilidade do uso de alguns códigos em outras areas sendo que é possivel criar um arquivo Utils ou Extension Functions contendo a boa parte dos codigos repetidos como funçao na tentativa de evitar repetiçao e facilitar na programaçao qual so ocorre no final do curso. Portanto, eu criei algumas pequenas funções Genericas como Extension Functions com base na necessidade e no curso.

package br.com.alura.games.utils

import org.springframework.util.StringUtils
import java.math.BigDecimal
import java.time.LocalDate
import java.time.Period
import java.time.format.DateTimeFormatter
import kotlin.random.Random
import kotlin.reflect.full.memberProperties

fun String.getAge(): Int {
        val pattern = "dd/MM/yyyy"
    try {
        val formatter = DateTimeFormatter.ofPattern(pattern)
        val dataNascimento = LocalDate.parse(this, formatter)
        return Period.between(dataNascimento, LocalDate.now()).years
    }catch (ex: Exception){
        throw Exception(
            "Não foi possivel converter \"$this\" em idade.\n" +
            "Formato obrigatorio: $pattern"
        )
    }
}

inline fun <reified T : Any> T.toStr(vararg exceptParams: String): String {
    val properties = T::class.memberProperties
    if (properties.isEmpty()) return "$this"
    return properties
        .filterNot { it.name in exceptParams }
        .joinToString("\n") { prop ->
            val value = prop.get(this)
            "(${value?.javaClass?.simpleName}) ${prop.name}: $value"
        }
}

inline fun <reified T:Any> T.toStrCapitalize(vararg exceptParams:String): String {
    val properties = T::class.memberProperties
    if (properties.isEmpty()) return "$this"
    return properties
        .filterNot { it.name in exceptParams }
        .joinToString("\n") { prop ->
            val value = prop.get(this)
            "(${value?.javaClass?.simpleName}) ${StringUtils.capitalize(prop.name)}: $value"
        }
}

inline fun <reified T> input(text: String, lowercase: Boolean = false): T {
    print(if (!text.endsWith("\n") && !text.endsWith(" ")) "$text " else text)
    val result = readLine() ?: ""

    return when (T::class) {
        BigDecimal::class -> result.toBigDecimal() as T
        Double::class -> result.toDouble() as T
        Float::class -> result.toFloat() as T
        Byte::class -> result.toByte() as T
        Short::class -> result.toShort() as T
        Int::class -> result.toInt() as T
        Long::class -> result.toLong() as T
        Boolean::class -> toBoolean(result) as T
        String::class -> (if (lowercase) result.lowercase() else result) as T
        Any::class -> result as T
        else -> {
            throw Exception("Tipo não suportado")
        }
    }
}

fun inputConfirm(text: String): Boolean {
    val answer: String = input(text, true)
    return (answer == "s" || answer == "sim")
}

fun toBoolean(str: String): Boolean? {
    val expr = str.trim().lowercase()
    return when {
        expr == "true" || expr == "t" -> true
        expr == "false" || expr == "f" -> false
        else -> throw IllegalArgumentException("Não é possível converter para Boolean")
    }
}

fun validateEmail(email: String): Boolean {
    val regex = Regex("^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,6}")
    return regex.matches(email)
}

fun numTag(max: Int): String {
    val num = Random.nextInt(max)
    return String.format("%04d", num)
}

Exemplo de uso

package br.com.alura.alugames.principal

import br.com.alura.alugames.modelo.Jogo
import br.com.alura.alugames.servicos.CheapSharkAPI
import br.com.alura.games.modelo.Player
import br.com.alura.games.utils.*

fun main() {
    var player = Player.build()
    println(player.toStr())
    do {
        val searchId: String = input("Digite um código de jogo para buscar:")
        val gameInfo = CheapSharkAPI().buscaJogo(searchId)
        var game: Jogo = Jogo(gameInfo)

        if (inputConfirm("Deseja inserir uma descrição personalizada? (S/N):")) {
            game.addDescription()
        } else {
            game.descricao = game.titulo
        }
        println("${game.toStr()}\n")

    } while (inputConfirm("Continuar procurando? (S/N):"))

    println("Jogos Procurados:\n")
    Jogo.jogos.forEach {
        println("${it.toStr("capa")}'\n") // o campo capa esta sendo ignorado ao mostrar os campos.
    }
    
}
1 resposta

Oii, Ademilson! Tudo bem?

Parabéns por colocar em prática o conteúdo da aula! A programação é muito interessante, pois existem "n" formas de fazer algo, o que traz boas consequências como um código mais limpo, sucinto, a lógica mais simplória e muito mais.

Continue interagindo no fórum compartilhando suas dúvidas, sugestões e projetos.

Bons estudos, Ademilson!