patternjavaMinor
OOP Battleship implementation in Java - part 2
Viewed 0 times
partjavabattleshipimplementationoop
Problem
Previous review can be found here
I got so many great tips on how to improve, so I've written a new version while trying to implement all the different suggestions.
So once again, any insight with regards to clean code, best practices etc. would be greatly appreciated.
Board.java
IGameField.java
ShipField.java
```
package com.tn.field;
import com.tn.game.Result;
import com.tn.ship.Ship;
public class ShipField implements IGameField {
private final Ship ship;
public ShipField(Ship ship) {
this.ship = ship;
}
@Override
public char getIcon() {
char icon;
Result shipState = ship.getState();
switch (shipState) {
I got so many great tips on how to improve, so I've written a new version while trying to implement all the different suggestions.
So once again, any insight with regards to clean code, best practices etc. would be greatly appreciated.
Board.java
package com.tn.board;
import com.tn.field.IGameField;
import com.tn.field.WaterField;
import com.tn.ship.Ship;
import com.tn.field.ShipField;
import com.tn.ship.ShipSize;
import java.awt.*;
import java.util.Scanner;
public class Board {
private static final char WATER = '~';
private static final int BOARD_SIZE = 10;
private static final char[] BOARD_LETTERS = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'};
private static final String HORIZONTAL = "H";
private static final String VERTICAL = "V";
private Scanner scanner;
private IGameField[][] board;
private static final Ship[] ships;
static {
ships = new Ship[] {
new Ship("Carrier", ShipSize.CARRIER),
new Ship("Battleship", ShipSize.BATTLESHIP),
new Ship("Cruiser", ShipSize.CRUISER),
new Ship("Submarine", ShipSize.SUBMARINE),
new Ship("Destroyer", ShipSize.DESTROYER)
};
}
public Board() {
this.scanner = new Scanner(System.in);
this.board = new IGameField[BOARD_SIZE][BOARD_SIZE];
for(int i = 0; i = 0
&& y = 0;
}
}IGameField.java
package com.tn.field;
import com.tn.game.Result;
public interface IGameField {
char getIcon();
Result shootAt();
}ShipField.java
```
package com.tn.field;
import com.tn.game.Result;
import com.tn.ship.Ship;
public class ShipField implements IGameField {
private final Ship ship;
public ShipField(Ship ship) {
this.ship = ship;
}
@Override
public char getIcon() {
char icon;
Result shipState = ship.getState();
switch (shipState) {
Solution
-
If you want to make
-
What is the purpose of the
-
-
Also every model you have can draw, which neglects separation of concerns. It can be hard to debug such things and can become pretty complicated. Always is a good idea to create a printer class which only can use
If you want to make
public static constants use interface.public interface Constants {
final String SIZE = 5;
}-
What is the purpose of the
Board class? It seems like a global controller for the whole game process. Those validations strive to be moved into some validator class (CollisionValidator or CollisionManager is the common class in the most games). I mean your Board class is doing drawing, validation and storing game-world objects at once. Pretty big and difficult to extend class.-
ShipSize is a redundant class (not to say it should be an enum). You use its values only in one place - at the static initializer. You can either move ships names and their sizes to some sort of Ships enum or use integers constants directly at your static initializer.public enum Ships {
CARRIER("Carrier", 5),
BATTLESHIP("Battleship", 4),
CRUISER("Cruiser", 3),
SUBMARINE("Submarine", 3),
DESTROYER("Destroyer", 2);
private String name;
private int size;
Ships(String name, int size) {
this.name = name;
this.size = size;
}
}-
Also every model you have can draw, which neglects separation of concerns. It can be hard to debug such things and can become pretty complicated. Always is a good idea to create a printer class which only can use
System.out.print, where all methods take entities with their values to print (entities ideally should not say how to print themselves).Code Snippets
public interface Constants {
final String SIZE = 5;
}public enum Ships {
CARRIER("Carrier", 5),
BATTLESHIP("Battleship", 4),
CRUISER("Cruiser", 3),
SUBMARINE("Submarine", 3),
DESTROYER("Destroyer", 2);
private String name;
private int size;
Ships(String name, int size) {
this.name = name;
this.size = size;
}
}Context
StackExchange Code Review Q#162174, answer score: 2
Revisions (0)
No revisions yet.