Marzo 10, 2021

Alcance de variables en Java

Reducir o ámbito

A seguinte frase que debe gravar a súa cabeza desde este momento:

Toda a variable debe ser declarada no ámbito máis curto posible.

Cando unha variable está declarada cun alcance máis extenso Do que é necesario, é só cuestión de tempo que usamos esa variable incorrectamente, causando confusión e invitounos a introducir o erro (se o alcance incorrecto non está en si mesmo e un erro …). Imos ilustralo cun exemplo:

public class MiClase {int contarUsuariosPorNombreIncompleto(String fragmentoNombreUsuario, String nombreUsuarios) {boolean encontrado = false;int totalEncontrados = 0;for (Usuario nombreUsuarioActual : nombreUsuarios) {if (nombreUsuarioActual.contains(fragmentoNombreUsuario)) {encontrado = true;}if (encontrado) {totalEncontrados++;}}return totalEncontrados;}public static void main(String args) {String fragmentoNombreUsuario = "Michael";String nombreUsuarios = {"Jhon Doole", "Michael Fletcher", "James 'Jimmy X' Donald"};int resultado = new MiClase().contarUsuariosPorNombreIncompleto(fragmentoNombreUsuario, nombreUsuarios);System.out.println("Total resultados: " + resultado);}}

Ao executar a clase anterior, podemos ver a seguinte saída por consola:

IV id = “fee6190673”

que pasou? Só un dos usuarios ten a cadea de Michael no seu nome, pero estamos informados de que hai dous nomes de usuario correspondentes. Cubrimos prácticamente a execución da chamada a :

  1. Inicio da primeira iteración:
    • atopado é
  • Totalmente atopado 0
  • Fin da primeira iteración:
    • atopado é
  • totalmente atopado 0
  • Comezando a segunda iteración:
    • atopado é
  • Totalmente atopado é 0
  • Fin da segunda iteración:
    • atopado é true
  • Inicio da terceira e última iteración:
    • descubriu que é true (pero debe ser false)
    • totalmente atopado 1
  • final da terceira e última iteración:
    • atopado é true
    • totalmente atopado 2
  • sen valorar que o uso de Dous bloques if para a lóxica do noso problema (atopar un usuario para un fragmento do seu nome) é totalmente innecesario, é o resultado da variable encontrado o que determina que aumentamos o contador totalEncontrados. O problema é que a variable encontrado debe ser reiniciada a falsa no inicio (ou final) de cada iteración, ou doutro xeito no momento en que atopamos unha coincidencia o resto das iteracións darán a Falso positivo:

    public class MiClase {int contarUsuariosPorNombreIncompleto(String fragmentoNombreUsuario, String nombreUsuarios) {boolean encontrado = false;int totalEncontrados = 0;for (Usuario nombreUsuarioActual : nombreUsuarios) {if (nombreUsuarioActual.contains(fragmentoNombreUsuario)) {encontrado = true;}if (encontrado) {totalEncontrados++;}encontrado = false;}return totalEncontrados;}// ...}

    Agora ao executar a nosa clase de novo, obtemos o resultado esperado para os datos que proporcionamos:

    Total resultados: 1

    Ben, xa resolvemos o noso erro odioso. Agora é hora de parar e avaliar a situación. Se está a pensar en deixar o código xa que é que: é inexperto (perdoable), ou ten présa (non perdoable), ou simplemente non me importa (punible).

    Esqueza o tipo de programador Queres ser, imos continuar. Non crees que estamos facendo un pouco de uso torcido da variable encontrado?:

    • Declámolo como unha variable de bloque (alcance local) . ..
    • … dentro do método
    • … pero só estamos a usar dentro do bloque for (un alcance local de formigón)

    Vostede recorda esa frase que debes gravar para disparar na túa cabeza?

    Calquera variable debe ser declarada na área máis pequena posible.

    A nosa variable está a ser declarada nunha zona superior á que é utilizado, e por debemos reducir o seu alcance:

    public class MiClase {int contarUsuariosPorNombreIncompleto(String fragmentoNombreUsuario, String nombreUsuarios) {int totalEncontrados = 0;for (Usuario nombreUsuarioActual : nombreUsuarios) {boolean encontrado = false;if (nombreUsuarioActual.contains(fragmentoNombreUsuario)) {encontrado = true;}if (encontrado) {totalEncontrados++;}}return totalEncontrados;}// ...}

    Agora que a variable está no seu alcance axeitado, o código orixinal está libre de erros e temos reduciu o uso da variable de tres a dous lugares, o que significa código máis limpo. Poderiamos reducir aínda máis o alcance da variable booleana? Neste caso particular si, eliminándoo por completo (non hai variable, non hai alcance):

    public class MiClase {int buscarNumeroUsuarios(String nombreParcialUsuarioBusqueda, String nombreUsuarios) {int totalEncontrados = 0;for (Usuario nombreUsuarioActual : nombreUsuarios) {if (nombreUsuarioActual.contains(nombreParcialUsuarioBusqueda)) {totalEncontrados++;}}return totalEncontrados;}// ...}

    Agora a nosa lóxica empresarial é moi sinxela de entender. A eliminación da variable encontrado non é técnicamente unha redución do alcance, se non é unha refactora (mellora de código).

    Deixa unha resposta

    O teu enderezo electrónico non se publicará Os campos obrigatorios están marcados con *