Quando correggere qualcosa che è "sbagliato" ma funziona bene

5

Versione breve:

Ho scritto un codice che non viene fatto "nel modo giusto" perché, quando l'ho scritto, non sapevo come farlo. Ora che so come farlo "nel modo giusto", come faccio a decidere come risolverlo?

Versione più lunga con dettagli:

java.util.DecimalFormat non è sicuro. Ho quello che è essenzialmente un oggetto Description immutabile che viene utilizzato su tutto il mio codice su molti thread diversi. Per risolvere questo problema, ho creato una classe wrapper SynchronizedFormatter che fondamentalmente si limita a racchiudere un blocco attorno ai metodi di DecimalFormat che uso.

Il modo giusto per farlo è usare un ThreadLocal . Non sapevo nemmeno cosa fosse quando ho scritto il codice la prima volta. Ne vale la pena risolvere? La versione synchronized funziona perfettamente. Come faccio a decidere, su questo in modo specifico e su questa situazione più in generale?

Inoltre, dovrei menzionare che ho bisogno di apportare altre modifiche a questa classe per ragioni più importanti di "Ho sbagliato la prima volta". Questo è quello che mi ha fatto pensare: se sto facendo un sacco di chiacchiere in questa classe, forse dovrei sistemare queste altre cose che sono nella mia lista. Ma poi temo la china scivolosa ...

Questo non è un duplicato di Quando refactoring perché Refactoring significa :

Improving a computer program by reorganising its internal structure without altering its external behaviour.

Questa domanda parla della modifica del comportamento del codice (ad esempio utilizzando synchronized rispetto a ThreadLocal . Forse non dovrebbe essere taggato .

    
posta durron597 28.01.2015 - 19:48
fonte

2 risposte

4

Una semplice soluzione sarebbe quella di sostituire i componenti interni del tuo wrapper per usare Threadlocal.

Quindi format() cambia da:

private DecimalFormat format = new ...;

private final Object lock = new Object();

public String format(double value){
    synchronized(lock) {
        return format.format(value);
    }
}

a

private ThreadLocal<DecimalFormat> format = new ThreadLocal(){
    public DecimalFormat initialValue(){
        return new ...;
    }
};

public String format(double value){
    return threadLocalFormat.get().format(value);
}

Questo ha il vantaggio che la nuova implementazione è protetta da thread senza costi di sincronizzazione delle chiamate e l'interfaccia per tutte le altre classi rimane la stessa. Quindi il cambiamento è localizzato in solo 1 classe.

    
risposta data 28.01.2015 - 19:58
fonte
1

Tutto si riduce alla gestione del rischio e al sentimento. Prova a stimare quanto segue:

  • Quanto sono grandi i costi dell'errore come nel codice in questo momento. Provoca costi ricorrenti? O costi in forma di rischio che potrebbe trasformarsi in un bug in futuro? Qual è il costo e la probabilità di tale errore?

  • Quanto sono grandi i costi per risolverlo adesso: Rischio di rompere qualcosa + il tempo necessario a te (e al resto del team).

Infine fai questo calcolo per ORA e per qualche tempo in futuro. Alcuni tipi di problemi non sono un grosso problema in questo momento, ma potrebbero trasformarsi in un brutto pasticcio tra un anno, ma sono anche molto più costosi da risolvere. Probabilmente vorrai correggerli ora.

Nella maggior parte dei progetti non lo farai con numeri reali, ma basandoti sui tuoi sentimenti istintivi.

In genere cerco di riservare del tempo per questo tipo di manutenzione del codice e di usarlo per i problemi con il massimo ritorno per investimento, e regolare il tempo totale per questo in modo che la mia base di codice rimanga costante, di alta qualità.

    
risposta data 29.01.2015 - 12:41
fonte

Leggi altre domande sui tag