Marzo 10, 2021

Scopo delle variabili in Java


Riduzione della scope

La frase successiva è necessario masterizzarla sulla testa da questo momento:

Tutte le variabili devono essere dichiarate nell’ambito più breve possibile.

Quando una variabile viene dichiarata più estesa Il necessario, è solo una questione di tempo che usiamo quella variabile in modo errato, causando confusione e ci ha invitato a introdurre bug (se lo scopo sbagliato non è in sé e un bug …). Lo illustreremo con un esempio:

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);}}

Durante l’esecuzione della classe precedente, possiamo vedere la seguente output per console:

Che cosa è successo? Solo uno degli utenti ha la catena Michael nel suo nome, ma siamo informati che ci sono due nomi utente corrispondenti. Copriamo virtualmente l’esecuzione della chiamata a :

  1. inizio della prima iterazione:
    • trovato è false
    • totalmente trovato 0
  2. fine della prima iterazione:
    • trovato è false
    • totalmente trovato 0
  3. Avvio della seconda iterazione:
    • trovato è false
    • totalmente trovato è 0
  4. fine della seconda iterazione:
    • trovato è true
    • Totalmente trovato 1
  5. Inizio della terza e ultima iterazione:
    • Trovato è true (ma dovrebbe essere false)
    • totalmente trovato 1

    >

  6. fine del terzo e ultimo iterazione:
    • trovato è true
    • totalmente trovato 2

senza andare a valore rispetto all’uso di Due blocchi if per la logica del nostro problema (trova un utente per un frammento del tuo nome) è totalmente inutile, è il risultato della variabile Quello che determina che aumentiamo il contatore totalEncontrados. Il problema è che la variabile dovrebbe essere riavviata su false all’inizio (o alla fine) di ciascuna iterazione, o altrimenti al momento in cui troviamo una coincidenza il resto delle iterazioni darà 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;}// ...}

Ora quando si esegue nuovamente la nostra classe, otteniamo il risultato atteso per i dati che abbiamo fornito:

Bene, abbiamo già risolto il nostro bug odioso. Ora è il momento di fermare e valutare la situazione. Se stai pensando di lasciare il codice come è quello: sei inesperto (perdonabile) o hai fretta (non perdonabile), o semplicemente non importa (punibile).

Dimentica che tipo di programmatore Vuoi essere, continueremo. Non pensi che stiamo facendo un piccolo uso contorto della variabile ?:

  • lo dichiariamo come variabile di blocco (ambito locale) . ..
  • … all’interno del metodo
  • … ma lo stiamo semplicemente usando all’interno del blocco for (una portata locale in più concreta)

Ricorda quella frase che devi registrare per sparare sulla tua testa?

Qualsiasi variabile deve essere dichiarata nella zona più piccola possibile.

La nostra variabile viene dichiarata in un’area superiore a quella in cui è usato, e con dobbiamo ridurre la sua portata:

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;}// ...}

Ora che la variabile è nella sua portata appropriata, il codice originale è privo di errori e abbiamo ridotto l’uso della variabile da tre a due luoghi, il che significa codice più pulito. Potremmo ridurre ulteriormente l’ambito della variabile booleana? In questo caso particolare sì, eliminandolo completamente (non vi è alcuna variabile, non c’è spazio):

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

Ora la nostra logica aziendale è abbastanza semplice da capire. La rimozione della variabile encontrado non è tecnicamente una riduzione dell’ambito, se non un refactoring (miglioramento del codice).

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *