Evita le anomalie DD

5

Ho questo problema chiamato da PMD (analizzatore di codice statico) più spesso che vorrei, e vorrei sapere come qualcuno con più esperienza di me lo scriverebbe. Il mio codice è funzionale ma lo trovo inelegante, quindi voglio sapere come altri programmatori scriverebbero questo pezzo.

Il caso è, in una petizione di rete / I da cui posso o non posso ottenere un risultato, ma il mio metodo genitore non è a prova di nulla, quindi devo sempre restituire qualcosa. Inoltre, non mi piacciono molti ritorni su un metodo.

public String getBingLocation(Coordinate... data)
{
    String response = "Not Retrieved";
    final Coordinate location = data[0];
    JSONObject locationData;
    try {
        locationData = NetworkManager.getJSONResult(ApiFormatter
                .generateBingMapsReverseGeocodingURL(location.Latitude, location.Longitude));
        if (null != locationData) {
            final String address = this.getAddressFromJSONObject(locationData);
            response = address;
        }
    } catch (final ClientProtocolException e) {
        LoggerFactory.consoleLogger().printStackTrace(e);
        return response;
    } catch (final JSONException e) {
        LoggerFactory.consoleLogger().printStackTrace(e);
        return response;
    } catch (final IOException e) {
        LoggerFactory.consoleLogger().printStackTrace(e);
        return response;
    } finally {
        location.Street = response;
    }
    return response;
}

Altro esempio:

public static Object loadObject(final String fileName, final Context context) {
    Object object = null;
    try {
        ObjectInputStream objectInputStream = null;
        try {
            final FileInputStream fileStream = context.openFileInput(fileName);
            objectInputStream = new ObjectInputStream(fileStream);
            object = objectInputStream.readObject();
        } catch (final ClassNotFoundException catchException) {
            LoggerFactory.consoleLogger().printStackTrace(catchException);
        } catch (final ClassCastException catchException) {
            LoggerFactory.consoleLogger().printStackTrace(catchException);
        } catch (final Exception catchException) {
            LoggerFactory.consoleLogger().printStackTrace(catchException);
        } finally {
            if (objectInputStream != null) {
                objectInputStream.close();
            }
        }
    } catch (final IOException catchException) {
        LoggerFactory.consoleLogger().printStackTrace(catchException);
    }
    return object;
}
    
posta MLProgrammer-CiM 01.02.2013 - 10:55
fonte

2 risposte

4

Parte del problema è che le tue funzioni hanno più di una responsabilità. Entrambi stanno ottenendo un risultato e gestendo gli errori. Stai anche diventando inutilmente sospeso cercando di evitare più punti di ritorno, che è una pratica rudimentale dalla programmazione C in cui può causare perdite di memoria. È necessario utilizzare più ritorni se chiarisce il codice, in particolare nelle funzioni brevi. Immagino anche che il tuo codice di registrazione venga ripetuto dappertutto. Se separi queste preoccupazioni e cerchi di evitare di ripetere te stesso, ottieni qualcosa di simile a questo:

public JSONObject getLoggedJSONResult(String api)
{
    try {
        return NetworkManager.getJSONResult(api);
    } catch (final ClientProtocolException e) {
        LoggerFactory.consoleLogger().printStackTrace(e);
    } catch (final JSONException e) {
        LoggerFactory.consoleLogger().printStackTrace(e);
    } catch (final IOException e) {
        LoggerFactory.consoleLogger().printStackTrace(e);
    }

    return null;
}

public String getBingLocation(Coordinate... data)
{
    final Coordinate location = data[0];

    JSONObject locationData = getLoggedJSONResult(
       ApiFormatter.generateBingMapsReverseGeocodingURL(
          location.Latitude, location.Longitude));

    if (null == locationData) {
        return "Not Retrieved";
    } else {
        return this.getAddressFromJSONObject(locationData);
    }
}

Come principio generale, la maggior parte delle anomalie DD può essere risolta dividendo la funzione. È principalmente una questione di capire dove dividerlo.

Il tuo secondo esempio è più complicato. Questo tipo di situazione è il motivo per cui sono state inventate le tentativo-con-risorse . Puoi utilizzare un ritorno anticipato per eliminare l'anomalia DD su object , ma non sarai in grado di fare molto su objectInputStream senza un try-with-resources.

    
risposta data 05.02.2013 - 19:50
fonte
0

Per quanto riguarda il tuo primo esempio, lo scriverei in questo modo:

public String getBingLocation(Coordinate... data)
{
    String response;
    final Coordinate location = data[0];
    JSONObject locationData;
    try {
        locationData = NetworkManager.getJSONResult(ApiFormatter
                .generateBingMapsReverseGeocodingURL(location.Latitude, location.Longitude));
        if (null != locationData) {
            final String address = this.getAddressFromJSONObject(locationData);
            response = address;
        } else {
            response = "Not Retrieved";
        }
    } catch (final ClientProtocolException e) {
        LoggerFactory.consoleLogger().printStackTrace(e);
        response = "Not Retrieved";
    } catch (final JSONException e) {
        LoggerFactory.consoleLogger().printStackTrace(e);
        response = "Not Retrieved";
    } catch (final IOException e) {
        LoggerFactory.consoleLogger().printStackTrace(e);
        response = "Not Retrieved";
    } finally {
        location.Street = response;
    }
    return response;
}

L'idea principale è di evitare di ignorare un valore senza leggerlo (questo significa che un assegnamento è inutile perché non letto mai).

Una soluzione deve avere una singola dichiarazione di ritorno e restituire una variabile non inizializzata. Quindi segui tutto il percorso possibile e verifica che un valore sia sempre assegnato e non più di una volta.

    
risposta data 05.02.2013 - 15:42
fonte

Leggi altre domande sui tag