我有这两个用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 内存方面是很昂贵的。那么解决这个重复代码问题的正确方法是什么呢?
你可以使用消费者来处理在 for
循环。定义一个新的功能接口,它把 xx
和 yy
值作为参数。
@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()
.
您可以定义 public void fillRect(bool plot, float x, float y, float width, float height,float transparency, Color color)
哪儿 plot
表示应该使用哪个实现。当false时,使用第一个选项。当为真时,使用第二个选项。