Is this violating the DRY principle?
Até certo ponto, sim - e acho um pouco surpreendente que alguns comentadores aqui pareçam ignorá-lo ou negá-lo. De fato, as conseqüências são geralmente aceitáveis em muitos casos do mundo real, mas acho que vale a pena dar uma olhada mais de perto no exemplo.
Então, vamos supor por um momento essa afirmação
for(let i=0;i<SharedData.students.length;i++){
SharedData.students[i].something=.....
aparece 100 vezes em um programa. Depois, há algumas decisões de design que já se tornaram mais difíceis de mudar:
-
a decisão de ter SharedData
um atributo chamado students
-
a decisão de que students
é uma matriz indexável
-
a decisão de que os alunos têm um campo mutável chamado something
(Claro, você não escreveu para repetir a parte interna do loop, mas deixe-me colocar isso neste exemplo para fins de demonstração)
Então, como você pode atenuar esses problemas? O primeiro pode ser mitigado, evitando repetir a expressão explícita SharedData.students
com mais frequência do que o necessário. Muitas vezes, uma variável local adicional simples pode ajudar:
let studentArray = SharedData.students;
for(let i=0;i<studentArray.length;i++){
studentArray.something=.....
Observe que essa simples alteração divide o número de repetições de SharedData.students
por dois. Em uma escala maior, você pode considerar ter várias funções implementadas em termos de um parâmetro studentArray
em vez de um parâmetro SharedData
.
O problema 2 pode ser mitigado, por exemplo, usando uma instrução foreach
, se sua linguagem de programação tiver algo assim:
foreach(student in studentArray){
student.something = ...
Agora, é necessário ter apenas students
um contêiner iterável, que é uma suposição mais fraca do que ser uma matriz indexável.
O problema 3 pode ser atacado pelo encapsulamento da parte interna do loop for
dentro de uma função:
foreach(student in studentArray)
DoSomething(student);
Agora, a lógica de manipular ou usar student
de uma maneira específica está em um lugar, não em 100 mais.
Talvez valha a pena dar uma olhada no porquê de um tal cabeçalho repete tantas vezes dentro de um programa. Pode ser um sinal de que a seção de código geral contendo o loop for
pode ser generalizada, talvez introduzindo a operação como um parâmetro em si (prefiro a sintaxe C #, suponho que você tenha a idéia):
void DoSomethingForAllStudents(Action<Student> DoSomething)
{
foreach(student in studentArray)
DoSomething(student);
}
Mas cuidado, isso já pode ser overengineered, e se o custo de tornar as coisas menos DRY é overengineering, muitas vezes você deve deixar essas coisas como são.
Como escrevi no início, em muitos casos do mundo real, os problemas nomeados são decisões de design que você não vai mudar mais tarde durante toda a vida do seu programa, ou onde o número real de repetições não é tão alto . Portanto, mesmo que isso literalmente viole DRY, não pense demais nisso.