Is this violating the DRY principle?
In un certo senso, si - e penso che sia un po 'sorprendente che alcuni commentatori qui sembrano ignorarlo o negarlo. In effetti, le conseguenze sono spesso accettabili in molti casi reali, ma penso che valga la pena dare un'occhiata più da vicino all'esempio.
Quindi supponiamo per un momento questa affermazione
for(let i=0;i<SharedData.students.length;i++){
SharedData.students[i].something=.....
appare 100 volte in un programma. Poi ci sono alcune decisioni di design che sono già diventate difficili da cambiare:
-
la decisione di avere SharedData
un attributo chiamato students
-
la decisione che students
è una matrice indicizzabile
-
la decisione che gli studenti abbiano un campo mutabile chiamato something
(Naturalmente, non hai scritto per ripetere la parte interna del ciclo, ma lascia che ti metta questo esempio a scopo di dimostrazione)
Quindi, come puoi mitigare questi problemi? Il primo può essere mitigato evitando di ripetere l'espressione esplicita SharedData.students
più spesso del necessario. Spesso, una semplice variabile locale aggiuntiva può aiutare:
let studentArray = SharedData.students;
for(let i=0;i<studentArray.length;i++){
studentArray.something=.....
Si noti che questo semplice cambiamento divide da solo il numero di ripetizioni di SharedData.students
per due. Su una scala più ampia, potresti considerare di avere diverse funzioni implementate in termini di parametro studentArray
invece di un parametro SharedData
.
Il numero 2 può essere mitigato, ad esempio, utilizzando un'istruzione foreach
, se il tuo linguaggio di programmazione ha una cosa del genere:
foreach(student in studentArray){
student.something = ...
Ora è solo necessario avere students
di un contenitore iterabile, che è un'ipotesi più debole rispetto a un array indicizzabile.
Il numero 3 può essere attaccato incapsulando la parte interna del ciclo for
all'interno di una funzione:
foreach(student in studentArray)
DoSomething(student);
Ora, la logica di manipolare o usare student
in un modo specifico è in un posto, non più 100.
Forse vale anche la pena di dare un'occhiata al motivo per cui una tale for-head si ripete così spesso all'interno di un programma. Potrebbe essere un segnale che la sezione di codice generale contenente il ciclo for
può essere generalizzata, magari introducendo l'operazione come parametro stesso (preferisco la sintassi di C #, immagino tu abbia l'idea):
void DoSomethingForAllStudents(Action<Student> DoSomething)
{
foreach(student in studentArray)
DoSomething(student);
}
Ma attenzione, questo può già essere sovrastimato, e se il costo di rendere le cose meno ESSENZIALI è eccessivamente complicato, è meglio lasciare le cose come sono.
Come ho scritto all'inizio, in molti casi reali i problemi citati sono decisioni di progettazione che non cambierai più avanti durante l'intera vita del tuo programma, o dove il numero reale di ripetizioni non è così elevato . Quindi, anche se questo letteralmente violando DRY, non pensarci troppo.