Home > Software design >  Create a board made of Cells able host a Generic value
Create a board made of Cells able host a Generic value

Time:05-20

I'm working on a project(a game) which will have a board to play on.

I want to make this board as generic as possible in order to be able to re-use the code for a possible other game.

public class Board {
    private int rows;
    private int cols;
    private Box[][] board;

    public Board(int rows, int cols){
        Box[][] board = new Box[rows][cols];
        for (int row = 0; row < this.rows; row  ){
            for (int col = 0; col < this.cols; col  ){
                board[row][col] = new Box();
            }
        }
    }

    public int getCols(){return this.cols;}
    public int getRows(){return this.rows;}

    public Piece getContentAtPos(int row, int col){
        return board[row][col].getContent();
    }
}

This is the Board class. The problem here is that I have to return a Piece object with the getContentAtPos() method because the Box (Cell) class is like this:

public class Box {
    private boolean empty;
    private Piece content;

    public Box(){
        empty = true;
    }

    public Box(Piece piece){
        empty = false;
        this.content = piece;
    }

    public boolean isEmpty(){
        return empty;
    }

    public Piece getContent(){
        if (!empty) {
            return content;
        } else {
            return null;
        }
    }
}

Whereas, the ideal for me would be the class Box to be able to host any type of object and return this generic object with getContentAtPos() via the Box getContent() method.

My generic Box class.

public class Box<T>{
    private boolean empty;
    private T content;

    public Box(){
        empty = true;
    }

    public Box(T content){
        this.content = content;
        empty = false;
    }

    public boolean isEmpty(){
        return empty;
    }

    public T getContent(){
        if (!isEmpty()){
            return content;
        }
        return null;
    }

    public T setContent(Object content){
        this.content = content;
    }
}

But what do I need to change in the Board class?

What return value shall I put there?

CodePudding user response:

You should create interface that every class you will return in the future will implement. This way you will be sure that return type will implement interface and have defined behaviour.

    public interface ReturnableBox { 
          public boolean isEmpty();
    }
    public class Board {

       private int rows;
       private int cols;
       private ReturnableBox [][] board;
   }
   public class Box implements ReturnableBox {
   //...
   }

CodePudding user response:

the ideal for me would be the class Box to be able to host any type of object and return this generic object with getContentAtPos via the Box getContent method

I guess you expect your game pieces to declare a certain behavior. If so, Box doesn't need to store an arbitrary object, but an object of type representing a contract that encompass all the methods which a game pieces is expected to have.

In other words you can define an interface, let's say Piece, which will have several implementations:

public interface Piece {
    // behavior of game pieces
}

public class MyGamePiece implements Piece {
    // implementations
}

You don't need to make Box class to be generic, instead it can contain a feild of type Piece:

public class Box {
    private boolean empty;
    private Piece content;
    
    // constractor and methods

    public Piece setContent(Object content){
        this.content = content;

    }
}

And method getContentAtPos() will also return an object of type Piece.

I want to make this board as generic as possible in order to be able to re-use the code for a possible other game.

That's a laudable aim.

Your classes have to be loosely coupled and narrow focused in order to be reusable. I.e. each class should a narrow and well-defined set of functionality and be aware only of those object that are crucial for it work (reduce coupling).

And you can make the necessary coupling loose (high coupling isn't good, but classes can't interact without coupling at all, you need to maintain balance) by introducing interfaces as shown above.

Even if eventually you would not use this code in other project, keeping it loosely coupled is beneficial because make it easier to maintain and expand it.

  • Related