Cosa fare con nomi di variabili lunghe?

4

Primo esempio:

countryRepository.getCountriesFromAsiaWhereAreTheMostPlanesAndBoats();
countryRepository.getCountriesFromAfricaWhereAreTheMostCars();

Questi nomi sono troppo grandi? In quale altro modo chiamiamo queste funzioni?

Stavo pensando ai parametri, ma secondo Martin Fowler, è meglio non usare i parametri nelle funzioni.

Secondo esempio:

Devo usare queste due variabili nella classe:

public static class CompareCountries {     
    public String[] countriesFromAsiaWhereAreTheMostPlanesAndBoats;
    public String[] countriesFromAfricaWhereAreTheMostCars;

    public CompareCountries (String countriesFromAsiaWhereAreTheMostPlanesAndBoats, String[] countriesFromAfricaWhereAreTheMostCars){
        this.countriesFromAsiaWhereAreTheMostPlanesAndBoats = countriesFromAsiaWhereAreTheMostPlanesAndBoats;
        this.countriesFromAfricaWhereAreTheMostCars = countriesFromAfricaWhereAreTheMostCars;
    }   

    public static String[] compares() {}
}

Qui più non posso usare i parametri.

    
posta paulbooker 03.03.2018 - 16:08
fonte

5 risposte

10

Non lasciare mai che un problema di stile del layout del codice ti motiva a ridurre un nome:

public static class CompareCountries {     
    public String[] countriesFromAsiaWhereAreTheMostPlanesAndBoats;
    public String[] countriesFromAfricaWhereAreTheMostCars;

    public CompareCountries (
            String countriesFromAsiaWhereAreTheMostPlanesAndBoats, 
            String[] countriesFromAfricaWhereAreTheMostCars
    ) {
        this.countriesFromAsiaWhereAreTheMostPlanesAndBoats =
            countriesFromAsiaWhereAreTheMostPlanesAndBoats
        ;

        this.countriesFromAfricaWhereAreTheMostCars = 
            countriesFromAfricaWhereAreTheMostCars
        ;
    }   

    public static String[] compares() {}
}

Tuttavia, cerca sempre di ottenere il punto rapidamente ed efficacemente. Non permettere mai inutili lanugine.

Si consideri:

asianContriesWithMostPlanesAndBoats
africanCountriesWithMostCars

Inoltre, trovo sorprendente che una classe la cui responsabilità è quella di "confrontare i paesi" riguarda solo l'Asia e l'Africa. Il nome della classe potrebbe essere più lungo. Non dovrei essere sorpreso quando guardo dentro.

    
risposta data 03.03.2018 - 16:35
fonte
8

Se davvero non vuoi usare i parametri, usa divide e conquista, a.k.a. SRP. Dividi la tua unica lunga chiamata in più, ad es.

getCountries()
  .fromAsia()
  .planesAndBoats()

Questo stile è spesso chiamato "interfaccia fluente".

    
risposta data 03.03.2018 - 17:48
fonte
1

Personalmente, sto bene con nomi di variabili lunghe, ma se fossi io, probabilmente chiamerei countriesFromAsiaWhereAreTheMostPlanesAndBoats qualcosa come topCountriesByAirSea .

Tuttavia, detto questo, se il costruttore sta ricevendo due elenchi di paesi, ciò che tali elenchi contengono non è rilevante per questa classe! E se è rilevante, probabilmente è un difetto di progettazione.

Se questo è il caso, probabilmente li chiamerei qualcosa come sourceCountries e targetCountries .

    
risposta data 10.03.2018 - 21:12
fonte
0

I nomi di variabili lunghe vanno bene, ma nel tuo esempio sembra essere dovuto a un problema più grande.

Che cosa succede se vengono aggiunti il Sud America, l'Europa e il Pacifico? Ci saranno nuovi metodi per ognuno di questi? Cosa succede se vengono aggiunti ancora più tipi di veicoli? Per ogni paese avresti bisogno di un nuovo metodo. Un modo migliore per farlo sarebbe fornire un modo per filtrare i dati sul repository invece di creare un nuovo metodo per ogni specifica istanza.

In C # potresti usare Linq. Non ho familiarità con Java, ma forse potresti creare estensioni come queste. In Python puoi usare le list comprehensions.

Potresti inserire una variabile che costituisca il "più" per auto / barche / aerei, per ora 100:

countryRepository.getCountries()
   .Where(c => c.Region == "Asia")
   .Where(c => c.NumberPlanes > 100 && c.NumberBoats > 100)
   .Select(c => c.Name);

countryRepository.getCountries()
   .Where(c => c.Region == "Africa")
   .Where(c => c.NumberCars > 100)
   .Select(c => c.Name);

O prendi i primi 10

countryRepository.getCountries()
   .Where(c => c.Region == "Africa")
   .OrderByDescending(c => c.NumberCars)
   .Take(10)
   .Select(c => c.Name);
    
risposta data 14.03.2018 - 20:37
fonte
0

Puoi ignorare i nomi di variabili lunghe aggiungendo più significato nel nome di una nuova classe.

Nel primo esempio, puoi creare diversi repository: AsiaCountryRepository e AfricaCountryRepository:

asiaCountryRepository.getWhereAreTheMostPlanesAndBoats();
africaCountryRepository.getWhereAreTheMostCars();

Nel secondo esempio, anziché utilizzare solo una classe CompareCountries , crea un CompareAsiaCountries e CompareAfricaCountries :

public static class CompareCountries {     
    public CompareAsiaCountries whereAreTheMostPlanesAndBoats;
    public CompareAfricaCountries whereAreTheMostCars;

    public CompareCountries (CompareAsiaCountries whereAreTheMostPlanesAndBoats, CompareAfricaCountries whereAreTheMostCars){
        this.whereAreTheMostPlanesAndBoats= whereAreTheMostPlanesAndBoats;
        this.whereAreTheMostCars= whereAreTheMostCars;
    }   

}

So che potrebbe non essere applicabile a tutti i casi e ho bisogno di un refactoring, ma a volte questa è una buona soluzione.

Più un esempio

Puoi anche usare il nome del pacchetto per aggiungere ulteriori informazioni sulle reali responsabilità della classe e della variabile all'interno.

Immagina di calcolare un credito da una persona straniera dall'Asia. Invece di avere qualcosa di simile:

import com.application;
com.application.CalculationService {

    public BigDecimal calculate(){
        BigDecimal valueCeditOfForeignerFromAsia = result()
    }

}

Puoi avere una classe con un nome significativo (come il mio ultimo esempio):

import com.application;
CalculationCreditForeignAsiaService {

    public BigDecimal calculate(){
        BigDecimal value = result();
    }

}

Oppure puoi avere una classe in un bel pacchetto con molto significato:

import com.application.credit.foreigner.asia;
CalculateService() {
    public BigDecimal calculate(){
        BigDecimal value = result()
    }
}
    
risposta data 14.03.2018 - 21:01
fonte

Leggi altre domande sui tag