2009-02-20 7 views
3

Comment voulez-vous obtenir l'idéal DRY rêvé dans cet exemple, dans la langue de votre choix:Comment suivez-vous DRY avec du code en utilisant les coordonnées x-y?

drawLine(Point(0, 0), Point(w, 0)); 
int curRowY = 0; 
for(int row=0; row<rowHeights.size(); row++) { 
    curRowY += rowHeights[row]; 
    drawLine(Point(0, curRowY), Point(w, curRowY)); 
} 

drawLine(Point(0, 0), Point(0, h)); 
int curColX = 0; 
for(int col=0; col<colWidths.size(); col++) { 
    curColX += colWidths[col]; 
    drawLine(Point(curColX, 0), Point(curColX, h)); 
} 

Note: Une multitude d'ad-hoc préprocesseur macros est susceptible d'être extrêmement moins lisible & écriture si c'est parti. Peut-être, dans ce cas, vous prenez DRY trop à l'extrême?

Répondre

9

La réponse est simple: les vecteurs. Par exemple.

repeatLines(Point start, Point end, Vector direction, int[] gaps) 
    { 
    drawLine(start, end); 
    for (int i = 0; i < gaps.Length; i++) 
     { 
     Vector vector = direction * gaps[i]; 
     start += vector; 
     end += vector; 
     drawLine(start, end); 
     } 
    } 

repeatLines(Point(0, 0), Point(0, w), Vector(1, 0), rowHeights); 
repeatLines(Point(0, 0), Point(h, 0), Vector(0, 1), colWidths); 
+0

Et nous avons un gagnant: l'idée clé ici est que repeatLines avait besoin d'un nouveau paramètre pour déterminer horizontalement et verticalement. Cela a l'avantage de pouvoir faire d'autres angles en utilisant d'autres vecteurs. – Godeke

+0

C'est en fait pas mal! Certainement cassé un mur pour moi: j'ai continué à penser aux 2 cas comme "horz & vert" que j'ai assimilé à "x & y". Le traiter comme un angle arbitraire est une bonne solution. –

+0

Oh oui! J'aime ça! – teedyay

0

Néanmoins, en tant qu'exercice académique, je suis impatient de voir si quelqu'un peut trouver une solution aussi lisible que votre code actuel - mais sans la duplication apparente!

+0

en effet: 'lisible' est la clé. –

1

[. Je suis d'accord avec Stewart, mais j'appuie sur un exercice académique]

Tricky ...

D'une certaine façon, vous n'êtes pas vraiment vous répéter; vous faites deux choses semblables (littéralement et figurativement) orthogonales les unes aux autres.

Je suppose que vous pouvez faire ce qui suit, mais il est plus lisible et certainement pas plus performant:

[pseudo C#]:

void DrawGrid() 
{ 
    DrawLines(w, rowHeights, true); 
    DrawLines(h, colWidths, false); 
} 

void DrawLines(int lineLength, int[] lineSeparations, bool isHorizontal) 
{ 
    MyDrawLine(Point(0, 0), Point(lineLength, 0), isHorizontal); 
    int offset = 0; 
    for (int i = 0; i < widths.length; i++) 
    { 
     offset += lineSeparations[i]; 
     MyDrawLine(Point(offset, 0), Point(offset, lineLength), isHorizontal); 
    } 
} 

void MyDrawLine(Point startPoint, Point endPoint, bool isHorizontal) 
{ 
    if (isHorizontal) 
    { 
     SwapXAndYCoordinates(startPoint); 
     SwapXAndYCoordinates(endPoint); 
    } 

    drawLine(startPoint, endPoint); 
} 

A la réflexion, je pense que cela est juste un idiot idée ... :-)

+0

Oui. Celui-ci est une application directe de DRY comme on le voit habituellement, mais n'améliore évidemment pas le code original. Pourtant, je suis curieux de savoir pourquoi ces situations (et similaires) ne semblent pas bénéficier DRY comme la plupart le font. –

0

Si votre grille est carré, je pense que ce qui suit pourrait fonctionner:

void drawGrid() 
{ 
    for(int i = 1, offset = 10; i <= numPoints; i++, offset += 10) 
    { 
     Point p = new Point(i * offset, i * offset); 

     drawHorizontal(p); 
     drawVertical(p); 
    } 
} 

void drawHorizontal(Point p) 
{ 
    drawLine(new Point(0, p.y), new Point(width, p.y)); 
} 

void drawVertical(Point p) 
{ 
    drawLine(new Point(p.x, 0), new Point(p.x, height)); 
} 
+0

ouais SI chaque cellule était carrée ET que toute la grille était carrée. mais ce n'est pas;] –

Questions connexes