"3 o più usa una per" una buona regola empirica?

5

Quando le operazioni ripetitive diventano un odore di codice? Ho letto questo articolo di Charles Petzold dove ha suggerito questo e mi chiedevo cosa ne pensasse la gente.

    
posta Morgan Herlocker 11.05.2011 - 23:25
fonte

3 risposte

10

No.

La domanda non è quante. 3 non è più "loop-ish" di 2.

La domanda è "For All" o "There Exists".

Se la condizione post è "per tutti", allora deve scrivere un ciclo. "Per tutti e due" o "per tutti e tre" non importa. Tutto ciò che conta è "per tutti".

Allo stesso modo, se la condizione post è "esiste", allora devi scrivere un ciclo. "Esiste in questi due" o "esiste in questi tre" non importa. Tutto ciò che conta è "esiste".

Se vuoi ottimizzare il micro e affermare che un "per tutti" che elabora due elementi non richiede veramente un ciclo, hai troppo tempo libero a disposizione per pensare a irrilevanti sottigliezze.

Se vuoi micro-ottimizzare e affermare che un "esiste" che sceglie tra quelle che sono (attualmente) due scelte, stai guardando troppo in profondità. Due scelte sono isomorfe per le scelte n . Basta scrivere il codice di scelta n e andare avanti.

Si prega di non micro-ottimizzare.

    
risposta data 12.05.2011 - 04:24
fonte
13

3 o più di cosa?

"Uno, due, molti" non è necessariamente un cattivo modo di pensare, come programmatore, ma la domanda più importante è davvero, cosa stai contando? Se non hai correttamente definito così, quindi la "regola" è poco più di una banalità vuota.

Se una classe ha 3 proprietà o più, le si rifatta in un array? Probabilmente non in circostanze normali, poiché ciò non farebbe altro che oscurare la semantica di quelle proprietà. Ma poi di nuovo, se quelle proprietà sono denominate Item1 , Item2 , Item3 , Item4 e così via, e sono tutte dello stesso tipo, allora forse vorrai inserirle in un array e usare un ciclo per scorrere su di loro.

Allo stesso modo, puoi usare questa "regola del pollice" per giustificare la sostituzione delle dichiarazioni switch o case (a seconda della lingua) con un dizionario o una mappa. Ma ciò che in realtà si trova è che, nella maggior parte dei casi, questo diminuisce in generale la leggibilità delle prestazioni e ; leggibilità, perché il codice decisionale è stato spostato più lontano dalla decisione stessa, e dalle prestazioni, perché i blocchi switch / case di grandi dimensioni sono già strongmente ottimizzati dal compilatore (solitamente come tabelle di salto).

Tecnicamente, è possibile astrarre virtualmente tutto della logica del programma in un insieme di regole e azioni e collegarle tutte in un motore di flusso di lavoro come WF o BizTalk. Ovviamente, come può dirti da qualsiasi sviluppatore che lo ha sperimentato, l'uso eccessivo di questi strumenti raramente si traduce in un sistema chiaro, affidabile, manutenibile o performante.

Aforismi e regole empiriche non possono sostituire il refactoring riflessivo e mirato. Come principio di progettazione, questo è chiamato Non ripetere te stesso (ASCIUTTO) . Per raggiungere questo obiettivo in qualsiasi misura utile, devi avere una visione chiara di ciò che costituisce un fact nel tuo dominio - e questo spesso tende a variare in base al dominio.

Questa è la domanda che dovresti porre - non solo ora, ma costantemente, mentre codifichi. Mi sto ripetendo qui? Sto dichiarando gli stessi fatti o prendendo le stesse decisioni più e più volte? Sì? Quindi refactoring. Altrimenti, lascia stare.

Il numero di istanze non ha molta importanza. Potresti avere solo una "cosa", ma puoi comunque decidere che vale la pena di creare un'astrazione perché potrebbe diventare molte cose. Allo stesso modo, potresti avere 10 "cose", ma se sai che non ci sarà mai un undicesimo, allora non avrebbe senso rifattorizzare. I test unitari sono un esempio di ripetizione che è spesso difficile e raramente utile da evitare. Dipende dalla situazione.

Quindi di nuovo, concentrati su che cosa viene ripetuto, e quanto spesso potrebbe essere ripetuto, non solo sul numero di volte in cui è ripetuto adesso. Non ci sono buone pratiche.

    
risposta data 12.05.2011 - 00:29
fonte
1

Dico di no, ma per ragioni che sono (penso) sottilmente diverse dalle risposte esistenti. Dico anche che non ti preoccupare.

Il punto chiave è la leggibilità e la manutenibilità. In passato, potrebbero esserci stati anche problemi di ottimizzazione, ma a questo punto il compilatore può probabilmente ottimizzare meglio (e sicuramente più coerentemente) di quello che è possibile, quindi è quasi sempre un problema.

Tuttavia, anche una semplice sequenza di istruzioni quasi identiche può essere più leggibile e mantenibile rispetto a un ciclo con espressioni basate sulla variabile di loop. Quante volte è certamente rilevante, ma potrebbero esserci casi particolari in cui potrei arrivare fino a dieci, forse di più. Sì, vorrei davvero tagliare e incollare.

Punto chiave: abbrevia la sequenza ripetuta. Se non è un one-liner, dovresti probabilmente inserire i dettagli in una funzione e sequenziare le chiamate. Questo vale per IMO anche se non ti preoccuperai di un ciclo breve, perché aiuta a richiamare l'attenzione visivamente sul pattern ripetuto (e su eventuali eccezioni a quel modello).

Il vantaggio di leggibilità è che i valori sono lì esplicitamente. A seconda del contesto, le espressioni potrebbero essere più leggibili o i valori potrebbero essere più leggibili. È soggettivo e dipende dal caso particolare. Certamente avere cinque chiamate in sequenza rende visivamente ovvio che è ripetuto cinque volte, mentre un loop potrebbe richiedere più attenzione.

La cosa della manutenibilità è che quando c'è un pattern che può essere sfruttato in un loop ora, quel pattern può a volte essere illusorio - i requisiti possono cambiare in un modo che rompe il pattern, rendendo il loop sia senza speranza o richiedendo condizionali che complicano esso. È possibile eseguire il loop su una tabella di dati per ovviare a questo problema, ma la scrittura della sequenza di voci della tabella non è in linea di principio diversa dalla scrittura di una sequenza di chiamate esplicite. Si potrebbe anche considerare un caso di scrittura di un interprete di macchina virtuale del caso speciale (il ciclo) con una sequenza di istruzioni senza loop (le voci della tabella di dati).

Una cosa, però - se il ciclo (o la sequenza) è abbastanza piccolo da rendere entrambe le opzioni valide, è difficile immaginare che sia un grosso problema in entrambi i casi. In questo senso, anche se il problema è la leggibilità / manutenibilità piuttosto che le prestazioni, questa è ancora inutile micro-ottimizzazione di leggibilità / manutenibilità. Non sono del tutto d'accordo con S.Lott perché non credo nelle regole assolute e assolute, ma certamente non sosterrei di sprecare tempo a preoccuparmi di questo.

In sostanza, un po 'di tempo trascorso a pensare a questo problema "in linea di principio" è una buona cosa, ma quando lavori, vai con il tuo primo istinto e - a meno che il risultato non sia chiaramente malvagio - lasciala e passa a cose più importanti.

    
risposta data 12.05.2011 - 04:55
fonte

Leggi altre domande sui tag