如果唯一不同的是在for循环中的方法调用,则避免重复的代码。

问题描述 投票:0回答:1

我有这两个用java写的方法,我习惯写这样的方法validateBoundary(float*x,float*y,float*width,float*height):void,其中包括'if-statments'和调用它。

public void fillRect(float x, float y, float width, float height, Color color) {
        int xi = mapX(x);
        int yi = mapY(y);

        int heightf =  mapHeight(height);
        int widthf  = mapWidth(width);


        if (xi + widthf > pixelWidth){
            widthf -= xi + widthf - pixelWidth;
        }
        if (yi + heightf > pixelHeight){
            heightf -= yi + heightf - pixelHeight;
        }


        if (xi < 0) {
            widthf += xi;
            xi = 0;

        }
        if (yi < 0) {
            heightf += yi;
            yi = 0;
        }

        for (int xx = xi; xx < xi + widthf; xx++){
            for (int yy = yi; yy < yi + heightf; yy++){
                // here is the difference between the other method
                setPixel(xx,yy,color);

            }
        }
    }
public void fillRect(float x, float y, float width, float height,float transparency, Color color) {
        int xi = mapX(x);
        int yi = mapY(y);

        int heightf =  mapHeight(height);
        int widthf  = mapWidth(width);

        if (xi + widthf > pixelWidth){
            widthf -= xi + widthf - pixelWidth;
        }
        if (yi + heightf > pixelHeight){
            heightf -= yi + heightf - pixelHeight;
        }


        if (xi < 0) {
            widthf += xi;
            xi = 0;

        }
        if (yi < 0) {
            heightf += yi;
            yi = 0;
        }

        for (int xx = xi; xx < xi + widthf; xx++){
            for (int yy = yi; yy < yi + heightf; yy++) {
                // here is the difference between the other method
                // this Method is slower then setPixel() 
                plot(xx,yy,transparency,color);
            }
        }
    }

我曾经写过这样的方法 validateBoundary(float* x,float* y, float* width, float *height): void,其中包括if -statments,然后调用它,但显然这在Java中不会发生。有什么办法可以解决这样的问题呢?我们可以写一个Methode validateBoundaryWidthf(xi, widhtf, pixelWitdth),返回widthf的新值。但是像这样的事情。

if (xi < 0) {
     widthf += xi;
     xi = 0;
}

因为只有一个返回值。当然,我可以创建一个带有 widthf 和 xi 属性的 POJO 来代替返回值,但我认为这样做在 cpu 内存方面是很昂贵的。那么解决这个重复代码问题的正确方法是什么呢?

java code-duplication
1个回答
3
投票

你可以使用消费者来处理在 for 循环。定义一个新的功能接口,它把 xxyy 值作为参数。

@FunctionalInterface
public interface PointConsumer {
    void accept(int x, int y);
}

然后你添加一个新方法 performOnPoints 含有所有需要的参数,并且有一个 PointConsumer 争论。它可能看起来像这样。

public void performOnPoints(float x, float y, float width,
                            float height, PointConsumer consumer) {
    int xi = mapX(x);
    int yi = mapY(y);

    int heightf =  mapHeight(height);
    int widthf  = mapWidth(width);


    if (xi + widthf > pixelWidth){
        widthf -= xi + widthf - pixelWidth;
    }
    if (yi + heightf > pixelHeight){
        heightf -= yi + heightf - pixelHeight;
    }


    if (xi < 0) {
        widthf += xi;
        xi = 0;

    }
    if (yi < 0) {
        heightf += yi;
        yi = 0;
    }

    for (int xx = xi; xx < xi + widthf; xx++){
        for (int yy = yi; yy < yi + heightf; yy++){
            consumer.accept(xx, yy);
        }
    }
}

然后你可以重写你现有的 fillRect 这样的方法。

public void fillRect(float x, float y, float width, float height, Color color) {
    performOnPoints(x, y, width, height, (xx, yy) -> setPixel(xx, yy, color));
}

public void fillRect(float x, float y, float width, float height,
        float transparency, Color color) {
    performOnPoints(x, y, width, height, (xx, yy) -> plot(xx,yy,transparency,color);
}

正如你所看到的,它们都使用相同的循环代码和所有特殊的 if() 语句,但你的这段代码只有一次。对于不同的参数,你将使用不同的消费者对象,其中一个将调用 setPixel(),另一个会叫 plot().


0
投票

您可以定义 public void fillRect(bool plot, float x, float y, float width, float height,float transparency, Color color) 哪儿 plot 表示应该使用哪个实现。当false时,使用第一个选项。当为真时,使用第二个选项。

© www.soinside.com 2019 - 2024. All rights reserved.