Как вы следуете за DRY с кодом, используя X-Y координат? - PullRequest
3 голосов
/ 20 февраля 2009

Как бы вы получили мечтанный СУХОЙ идеал в этом примере на выбранном вами языке:

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));
}

Примечание. Множество специальных макросов препроцессора, вероятно, будут чрезвычайно менее читаемыми и доступными для записи, так что этого нет

Ответы [ 4 ]

9 голосов
/ 20 февраля 2009

Ответ прост: векторы. Э.Г.

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);
1 голос
/ 20 февраля 2009

[Я согласен со Стюартом, но продолжаю как академическое упражнение.]

Tricky ...

В некотором смысле, вы не действительно повторяете себя; вы делаете две похожие вещи, которые (в прямом и переносном смысле) ортогональны друг другу.

Полагаю, вы могли бы сделать следующее, хотя оно не более читабельно и, конечно, не более производительно:

[псевдо 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);
}

Если подумать, я думаю, что это просто глупая идея ...: -)

0 голосов
/ 20 февраля 2009

Если ваша сетка квадратная, думаю, может сработать следующее:

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 голосов
/ 20 февраля 2009

Может быть, в этом случае вы принимаете DRY слишком сильно?

Тем не менее, как академическое упражнение, я с нетерпением жду возможности узнать, сможет ли кто-нибудь придумать решение, столь же удобное для чтения, как ваш текущий код, - но без очевидного дублирования!

...