Prusio
Prusio

Reputation: 425

Reducing number of similar methods

I have a method which does something from point a to point b (it iterates by incrementation) or from b to a (it iterates by decrementation) through an array.

These two methods have to be a to b and b to a because I do not know at the beginning, where will I end. In my implementation, they vary only in one line.

In more dimensions I still do it only in straight lines. Problem expands from two (left, right) to eight (up, up-right, right, down-right etc.), 32 and so on functions. They also start varying in more lines.

What is the best way to deal with the problem?

I have to deal with it in java.

Example in 2 dimensions (three from eight functions to cover every possibility):

void doSomethingToCellsRIGHT(int x, int y) {
    while(condition) {
        board[x][y].changeSomething();
        x++;
    }
}

void doSomethingToCellsLEFT(int x, int y) {
    while(condition) {
        board[x][y].changeSomething();
        x--;
    }
}
void doSomethingToCellsUP_LEFT(int x, int y) {
    while(condition) {
        board[x][y].changeSomething();
        y++;
        x--;
    }
}

Upvotes: 1

Views: 91

Answers (3)

maaartinus
maaartinus

Reputation: 46482

The answer by Liping could be an improvement, except for that the method

    public void move(int x, int y) {
        x++;
    }

does nothing at all (incrementing a local variable is a no-op here).

Anyway, I'd do it in a shorter and probably faster way:

public interface Move {
    public int dx();
    public int dy();
}

@RequiredArgsConstructor 
public enum Movement implements Move {
    RIGHT(+1, 0),
    LEFT(-1, 0),
    UP(0, +1),
    DOWN(0, -1);

    private final dx;
    private final dy;
}

The Lombok annotation does exactly what the name says.

The usage should be obvious.

Upvotes: 1

Liping Huang
Liping Huang

Reputation: 4476

Cool, a good question, the codes are quite the same with @Derek but make it more OO:

Define the Move interface

public interface Move {
    public void move(int x, int y);
}

Implement it in the enum with method body

public enum Movement implements Move {
    RIGHT() {
        public void move(int x, int y) {
            x++;
        }
    },

    LEFT() {
        public void move(int x, int y) {
            x--;
        }
    },

    UP() {
        public void move(int x, int y) {
            y++;
        }
    },

    DOWN() {
        public void move(int x, int y) {
            y--;
        }
    };
}

How to use:

public void doSomething(int x, int y, Movement... movements) {
    while (condition) {
        board[x][y].changeSomething();

        for (Movement movement : movements) {
            movement.move(x, y);
        }
    }
}

Call

doSomething(1, 2, Movement.DOWN, Movement.RIGHT);

Upvotes: 1

Derek Lawrence
Derek Lawrence

Reputation: 1588

add an enum

public enum DIRECTION {
    Right,
    Left,
    Up,
    Down
}

You could do this and have multiple optional parameters, where you always need at least one direction;

void doSomethingToCells(int x, int y, DIRECTION... directions){
    while(condition){
        board[x][y].changeSomething();

        for(DIRECTION dir:directions){  
            y+= dir == DIRECTION.Up ? 1 : 0;
            y-= dir == DIRECTION.Down ? 1 : 0;
            x+= dir == DIRECTION.Right ? 1 : 0;
            x-= dir == DIRECTION.Left ? 1 : 0;
        }
   }
}

and you can call

doSomethingWithCells( 1,1, Up, Left) . // This would go x-- and y++
doSomethingWithCells( 1,1, Up)         // This would go y++

You could even call

doSomethingWithCells( 1,1, Left, Left) .  //This would skip every second cell to the left

Upvotes: 2

Related Questions